Subclassing NSPredicate to add operator - objective-c

Cocoa defines predicate classes (NSPredicate, NSExpression, etc.) which "provide a general means of specifying queries in Cocoa" Predicate Programming. This set of classes describes what I need but with one little short-coming : I'd like additional operators.
NSComparisonPredicate already handles 14 operators (NSPredicateOperatorType) but I would like to add, say, temporal operators... or operators to represent things such as:
" variable has at least n entries" (binary operator)
" variable has value for, at most, n consecutive days" (ternary operator)
Obviously, I would need to implement these myself and the data model on which such queries are performed will have to support these operators. But, is there a way to implement it and benefit from the existing NSPredicate classes? Since operators were defined as an enum, I doubt I can extend on that front. Or am I completely missing the boat on this?!

Having spent a lot of time playing around with NSPredicate, I'm not sure this is the greatest idea.
Theoretically, you'd subclass NSPredicate, create your new initializer and properties, and then override the -evaluateWithObject:substitutionVariables: method to do your custom comparison.
Practically, it's probably a lot more difficult than that.
You might consider using FUNCTION() instead. I wrote a blog post about FUNCTION a while ago and how it plays with NSExpression and therefore with NSPredicate. Personally, I'd probably go with this, because then you could still use the +predicateWithFormat: syntax to create the NSPredicate. Creating a subclass to add an operator would necessarily prevent you from using the built-in parser.

Related

Why Filter is structural while Interpreter is behavioral?

Both Filter and Interpreter Design Patterns look like much similar task oriented. Filter does filtering a list for some criteria, while Interpreter is doing pretty much same for a single element.
But I wonder why Filter is Structural and Interpreter is behavioral. Anyone got an idea?
Although it is true that they are "task-oriented", these two patterns actually refer to different purposes, let's take the example of an SQLTable class.
Filter pattern can serve to filter/remove/hide, more generally affect the structure of your database but don't modify its behavior at all.
Example 1 : Once filtered, it's only a new SQLTable with less/more rows and maybe less/more columns
Interpreter pattern belongs to behavioral pattern, in the sense that it modifes the behavior of an object (often represented with the help of a structural pattern such as Composite). The difference lies in the interpretation of the structure to behave differently.
Example 2: Once interpreted as a csv-table, your SQLTable can now be exported to a PDF file
I guess your misunderstanding comes from the fact that they are both applied to a structure in order to create something else but the actual difference lies in their intent rather than their concrete implementation which are relatively close in practice

variable naming conventions for when desired name is already defined

Is there a convention for naming a variable when the name you want is already defined by the language? As an example, I'm currently coding a lisp function that takes two parameters, min and max. Vim's syntax highlighter colors those words though, so it looks like they're already lisp functions. I assume it'd be better to give the parameters different names.
Should I use completely different names? min and max are both short and descriptive though, so I'd like to use them if possible. Should I use a prefix, like myMin and myMax? I'm currently leaning towards that idea. Any suggestions would be helpful.
If you are looking for a very general naming convention - the one that would work well with all names reserved/defined in your language or framework - I really doubt that such convention would be practical or even useful.
I think you should do it on a (common) case by case basis.
Your example looks like one of such common cases: it probably is quite common for functions to have two parameters specifying some range of values. Well, in that case, I'd probably go with names like minValue and maxValue - they seem to be abstract enough to work well in most situations.
BTW, I would not use a prefix like my. However, if you were open to the idea of Apps Hungarian (see discussion on Wikipedia and Joel Spolsky's article), the answer to your question would be much simpler: just use a proper semantic prefix in the names of your parameters (e.g. xMin and xMax for min and max abscissa values).

load record by predicate/lambda via vb.net linq

im pretty confused about lambdas and actually im not even sure i need them here
what im trying to do here is write a function that will return an object from a certain table with a certain criteria
so lets say i can write
function GetRecord(TableName as string,Criteria as string) as object
'do the linq-stuff
end function
now i dont care if the paremeters are strings or lambdas or whatever, but the end result must be that at runtime i dont know which table and which criteria will be used
as sometimes i need to get a customer record by email and sometimes a product by id etc.
if possible i would prefer returning a list of matching objects and then i would just use .firstordefault when i want 1 (such as by id...)
thank you , as always, for taking the time to read this and answer!
all the best
Have you considered using Dynamic LINQ?
Example:
Parsing an expression tree can be a challenging but rewarding method of solving this issue. I think it's overkill and I'd go with Dynamic Linq as decyclone mentioned.
A benefit of parsing the expression tree, however, is that you can have compile time checking of the submitted criteria.
Here are some articles that helped me.
How to: Implement an Expression Tree Visitor: http://msdn.microsoft.com/en-us/library/bb882521(VS.90).aspx
Building a custom IQueryable Provider: http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx
Walkthrough: Creating an IQueryable LINQ Provider: http://msdn.microsoft.com/en-us/library/bb546158(v=VS.90).aspx
Expression Tree Basics:
http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx

How to handle null when comparing equality of value objects?

Note: I use C# as an example, but the problem is virtually the same in Java and probably many other languages.
Assume you implement a value object (as in value object pattern by M. Fowler) and it has some nullable field:
class MyValueObject
{
// Nullable field (with public access to keep the example short):
public string MyField;
}
Then, when overriding Equals(), how do you treat the case when both value objects have their MyField set to null? Are they equal or not?
In C#, treating them as equal seems obvious, because:
This is the behaviour of Equals() when you use a C# struct instead of a class and do not override Equals().
The following expressions are true:
null == null
object.ReferenceEquals(null, null)
object.Equals(null, null)
However, in SQL (at least in SQL Server's dialect), NULL = NULL is false, whereas NULL is NULL is true.
I am wondering what implementation is expected when using an O/R mapper (in my case, NHibernate). If you implement the "natural" C# equality semantics, may there be any ill effects when the O/R mapper maps them to the database?
Or maybe allowing nullable fields in value objects is wrong anyway?
Since ORMs know the relational model, they usually expose a way to query using SQL semantics.
NHibernate, for example, provides the is [not] null operator in HQL, and Restrictions.Is[Not]Null in Criteria.
Of course, there's an API where these paradigms collide: LINQ. Most ORMs try to do the right thing when comparing to null (i.e. replacing with is null), although there can be issues some times, especially where the behavior is not obvious.
Personally what I think is that if it can be null (in error free code), then they should be treated as equal.
However, if it shouldn't be null(ie: a Name for a Customer, or a Street Address for a Delivery) then it should never get to null in the first place.
I think you have two issues:
One being that you need to know if one instance of MyValueObject is equal to another instance.
And secondly, how that should translate to persistence.
I think you need to look at these separately as it seems that your angle is coupling them too close to each other which seems to me to violate some DDD principals - the Domain should not know/care about the persistence.
If you are unsure of the effect of the null value of MyField either (a) have it return a different Type other than string; (b) have it return a derivitave of string like EmptyString (or similar Special Case implementation); (c) or override the Equals method and specify exactly what it means for these instances to be equal.
If your ORM can not translate a particular expression (that involves MyValueObject) to SQL then perhaps its ok to do the harder work in the persistence layer (have the compare happen out of the SQL translation - yes, performance issues i know, but im sure not impossible to solve) in favour of keeping your Domain Model clean. It seems the solution should derive from "what's best for the domain model" to me.
#James Anderson makes a good point. Reserve null for error and failure states. I think Special Case seems more and more appropriate.

Why are many languages case sensitive?

Why are many languages case sensitive?
Is it simply a matter of inheritance? C++ is case-sensitive because C is, Java is case-sensitive because C++ is, etc.? Or is there a more pragmatic reason behind it?
I don't think you'll get a better answer than "because the author(s) of that language thought it was better that way". Personally, I think they're right. I'd hate to find these lines anywhere in the same source file (and refer to the same object+method)...
SomeObject.SomeMethod();
...
SOMEOBJECT.SOMEMETHOD();
...
someObject.someMethod();
...
sOmEoBjEcT.sOmEmEtHoD();
I don't think anyone would be happy to see this...
Unix.
Unix was case sensitive, and so many programming languages developed for use on Unix were case sensitive.
Computers are not forgiving - an uppercase character is not the same thing as a lowercase character, they're entirely different. And back when processing cycles, RAM and so forth were expensive it wasn't seen as worth the effort to force compilers and computers to be "forgiving", people were just trying to get the things to work.
Notice how case insensitivity didn't really become something useful until things like Visual Basic came along - once companies started to get invested in the concept that getting the masses to program was a good thing for their bottom line (i.e., Microsoft makes more money if there're more programs on Windows) did the languages start to be friendlier and more forgiving.
One interesting thing to consider is that English is also case-sensitive. (I suspect this is true for most natural languages, but it may well not be true for all.)
There's a big difference (where I live, anyway, near the town of Reading) between:
I like reading.
and
I like Reading.
Similarly, while many people do capitalise incorrectly, and you can usually understand what is meant, that doesn't mean such writing is considered correct. I'm a stickler when it comes to this kind of thing, which is not to say I get everything right myself, of course. I don't know whether that's part of the inheritance of programming language case sensitivity, but I suspect it may be.
One distinct advantage of case sensitivity for programming languages is that the text becomes culturally insensitive as well. It's bad enough having to occasionally spell out to a compiler which text encoding is used for a source file - having to specify which culture it's in would be even worse :(
It's actually extremely practical, both for the developer and for the language syntax specification: lower/upper case distinction adds a great deal of expressiveness to identifier naming.
From the point of view of the language syntax, you can force certain identifiers to start with a lower or upper case (for instance Java class name). That makes parsing easier, and hence helps keeping the syntax clean.
From a developer point of view, this allows for a vast number of convenient coding conventions, making your code clearer and easier to understand.
My guess would be that case sensitivity enlarges the name space. A nice trick such as
MyClass myClass;
would be impossible with case-insensitive compiler.
Case folding is only simple in English (and for all characters < 128). The German sz or "sharp s" (ß) doesn't have an upper case variant in the ISO 8859-1 charset. It only received one in Unicode after about a decade of discussion (and now, all fonts must be updated...). Kanji and Hiragana (Japanese alphabets) don't even know lower case.
To avoid this mess, even in this age of Unicode, it is not wise to allow case folding and unicode identifiers.
ExpertSexChange
I believe this is a competitor to Stack Overflow where you have to pay to read answers. Hmm... with case insensitivity, the meaning of the site's name is ambiguous.
This is a good reason for languages being case-sensitive. Less ambiguity! Ambiguity to programmers is considered yucky.
Back when parsing and compiling was real expensive and would take all night it was advantageous to the compiler if it didn't have to worry about case.
Once identifiers came in to existence that were only unique via their case it became very difficult to go back. Many developers liked it and there doesn't seem to be a big desire to undo it.
Case sensitivity adds to language readability by the use of naming conventions. You can't write
Person person = new Person("Bill");
if your language is case insensitive, because the compiler wouldn't be able to distinguish between the Class name and the variable name.
Also, having Person, person, PersoN, PeRsOn, and PERSON, all be equivalent tokens would give me a headache. :)
What is the capital form of i? I (U+0049) or İ (U+0130)?
Capitalization is locale dependent.
Because they're as dumb as a box of frogs, for precisely the reasons given for the opposite viewpoint in this thread (I'm not even gonna ask what that's about. Wood for the trees and all that).
When FOOBAR = FooBar = foobar, you get to choose your convention, and other coders can do the same whether they share your preference or not. No confusion.
They also can't get away with the stroke of genius that is having a constant, function and variable all with the same name in the same file, albeit with different caps. Again, no confusion.
You call your variable WebSite, they call theirs Website, and which system gets confused? Not an easy catch either, when you're scanning.
As for lookups, is it really that much more processing to convert the name to lowercase before looking it up? Doing your own premature optimisation is one thing, expecting it from the developer of your language of choice is a whole other level of missing the point.
...and yet, all these answers saying case-sensitivity reduces confusion. Sigh
Many (non-programming) languages (e.g. European using the Roman alphabet) are case-sensitive, so it's natural for native speakers of those languages to use upper- / lower-case distinctions.
The very idea that programming languages wouldn't be case-sensitive is a historical artifact arising from the limitations of early-generation hardware (including pre-computer teletype machines that used a 5-bit character code).
People who argue for case-blind languages must be unable to distinguish
IAmNowHere
from
IAmNowhere
(It's a joke! ;-)
There's also Common Lisp, which is a case-sensitive language that many people mistakenly believe is case-insensitive. When you type (car x) into the Listener, it turns into (CAR X) for processing. It is possible to define symbols with lower-case names, but they have to be quoted with something like |lower-case-symbol|. Therefore, typing in (car x) or (CAR X) or (Car X) all works the same.
(Franz Lisp was at one point introducing what they called "modern" capitalization, in which the Listener would not fold cases, and CL keywords would be in lowercase. I never followed it well enough to know what happened there.)
The upper-case of a letter isn't a universal concept. Java uses Unicode, so if you wanted case-insensitive Java, the meaning of your program could change depending on what locale it was compiled in.
Most languages don't let you put dots or commas (or apostrophes or spaces) in the middle of integer literals, probably because that's also locale-dependent.
From
.NET Framework Developer's Guide
Capitalization Conventions, Case-Sensitivity:
The capitalization guidelines exist
solely to make identifiers easier to
read and recognize. Casing cannot be
used as a means of avoiding name
collisions between library elements.
Do not assume that all programming
languages are case-sensitive. They are
not. Names cannot differ by case
alone.
How do you yell if you don't HAVE CAPS?! AHHH!
You have to be expressive. But in all honesty, of all the people in the world, those who work with programming logic would be the first to insist that differences are in fact differences.
I have read this entire thread. I must believe that those that report to have found value in case sensitivity have never programmed in a true high level language (which by definition is case insensitive). K&R admit that C is mid-level. After programming in Pascal, Delphi, Lazarus, ADA, etc, one learns that highly readable code is simple to write and to get to run quickly without obsessing on terse case sensitive constructs. After all, readability is the first and last word on the subject. Code is written for the human, not the computer. No problems to debug with case insensitive code.
When one moves down to a mid-level language, one finds that there are NO advantages to case sensitivity. There are however, a considerable number of hours spent debugging case sensitivity caused problems. Especially when patching together modules from different coders.
It also appears that a large number of respondents do not understand what is meant by case insensitivity. Only the characters a-z are affected. These are a sequential subset of ASCII characters. Three or four bytes of machine code make the compiler indifferent to case in this range of characters. It does not alter under-bar, numerals, or anything else. The points about other languages and character sets simply do not apply to this discussion. The compiler or interrupter would be coded to temporarily convert or not convert the character for analysis at compile time based on the being ASCII or not.
I am shocked at the new languages like Python that have come out repeating the mistake that K&R made. Yes they saved half dozen bytes in an environment where the total RAM for compiler, source, and object code was 1000 bytes. That was then. Now Memory is not a problem. Now, for no sensible reason, even the reserve words in Python are case sensitive! I do not think I will need to use "For" of "Print" as variable or function name. But that possibility has been preserved by the expensive of the time spent contenting with the interrupter over the exact case of each identifier. A bad deal I think.
The closest thing I have read to date in support of case sensitivity is the comments on Hashing. But these rare coding events that can be handled with careful attention to detail do not seem to be to be worth the pointless scrutiny a coder must use to write case sensitive code. Two views of the problem. One encourages bad coding, set traps in the code, and requires extra attention to be diverted away from bigger concepts. The other has no down side, has worked flawlessly in high level languages, and allows flexibility were it does no harm. It looks to me like yet another case of VHS wins over BETA. It's just my two cents worth here.
Lots of people here have said that it would be bad for several forms of capitalization to refer to the same thing, e.g.:
person
perSoN
PERSON
What would be really bad is if these all referred to different objects in code. If you've got variables person, perSoN and PERSON all referring to different things, you've got a problem.
Case sensitivity doesn't really help case consistency.
Foo.Bar
foo.Bar
fOO.bAR
In a case insensitive language that can be fixed automatically by the editor easily.
In a case sensitive language fixing it it's harder as it may be legal. The editor first has to ckeck if foo.Bar and fOO.bAR exist and also has to guess that you typed with the wrong case rather than forgetting to declare the variable (as Foo is different to fOO).
Every example I've seen supporting case sensitivity is based on a desire to write bad, undescriptive code. e.g. the "date" vs. "myDate" argument - these are both equally undescriptive and bad practice. Good practice is to name it what it actually is: birthDate, hireDate, invoiceDate, whatever. And who in their right mind would want to write code like:
Public Class Person
Public Shared ReadOnly PERSON As Person
End Class
Public Class Employee
Public person As Person = person.PERSON
End Class
Amazingly this is perfectly valid case insensitive VB.Net code. The thought that case sensitivity allows you to even more flagrantly disobey good programming practice is an argument against it, not for it.
I think having a case-sensitive language ENCOURAGES people to write poor code.
Const SHOESIZE = 9
Class ShoeSize
ShoeSize.shoesize = SHOESIZE
call shoeSize(ShoeSize);
function shoeSize(SHOEsize)
{
int ShoeSIZE = 10
return ShoeSize
}
Duh. You couldn't think of a better variable name than "ShoeSize" for the different purposes? There is a billion different words you could use, but you choose to just keep using ShoeSize instead?
Because many people find employeeSocailSecurityNumber just as readable as employee_social_security_number and it is shorter.
And you could also (foolishly) just use single-letters ("a" and "b" and "c") for all classes, variables, functions, and methods.
But WHY would you want to?
Use names that make sense, not:
function a(a)
{
int a = a.a;
return a
}
By typical coding standards, Person would be a class, person a variable name, and PERSON a constant. It's often useful to use the same word with different capitalization to mean something related but slightly different.
So, if you had three staff members in your business all called Robert, you'd refer to them as Robert, robert and ROBERT would you? And rely on people to know exactly which one you meant?
Give them email addresses such as Robert#widgets.com, robert#widgets.com, and ROBERT#widgets.com if your email system was case sensitive?
The potential for an unauthorised breach of personal data would be huge. Not to mention if you sent the database root password to the disgruntled employee about to be sacked.
Better to call them Bob, Robbie, and Robert. Better still to call them Robert A, Robert B and Robert C if their surnames were e.g. Arthur, Banks, and Clarke
Really - why on earth have a naming convention that invites mistakes or confusion, that relies on people being very alert? Are you so short of words in your volcabulary?
And as for the person who mentions the supposedly handy trick "MyClass myClass" - why, why why? You deliberately make it difficult to see at a glance whether a method used is a class method or an instance method.
Plus you lost the chance to tell the next person reading your code more about the particular instance of the class.
For instance.
Customer PreviousCustomer
Customer NewCustomer
Customer CorporateCustomer
Your instance name needs to ideally tell your colleague more than just the class it's based on!
Learning is always easier by example so here it goes:
C#(case sensitive but usable from VB.NET which is case insensitive):
CONSTANT_NAME
IInterfaceName // Uses I prefix in all case sensitive and insensitive languages
ClassName // Readable in both case sensitive and insensitive languages
_classMember // sometimes m_classMember or just classMember
DoSomething(someParam) // Method with action name, params can be _someParam
PropertyName // Same style in case sensitive and insensitive languages
localVariable // Never using prefix
Java and JS use a style similar to C# but methods/functions/events are declared like variables doSomething, onEvent.
ObjectPascal(Delphi and Lazarus/FPC are case insensitive, like ADA and VB.NET)
CConstantName // One can use Def or no prefix, not a standard
IInterfaceName
TClassName // Non-atomic types/classes have T prefix e.g. TStructRecordName
PSomePointer // Pointers have types, safer low level stuff
FClassFieldMember // F means Field member similar to m
DoSomething(Parameter) // Older code uses prefix A for parameters instead
PropertyName
LLocalVariable // Older code uses prefix for parameters not local vars
Using only OneCase and prefixes for each type makes sense in all languages. Even languages that started without prefixes have newer constructs like Interfaces that don't rely on case but use a prefix instead.
So it's really not important if a language is case sensitive or not. Newer concepts were added to case sensitive languages that were too confusing to be expressed by case alone and required using a prefix.
Since case sensitive languages started using prefixes, it's only reasonable to stop using case with the same identifier name someIdentifier SomeIdentifier SOME_IDENTIFIER, ISomeIdentifier and just use prefixes where it makes sense.
Consider this problem:
You have a class member called something, a method/function parameter called something and a local variable called something, what case convention could be used to easily differentiate between these ?
Isn't it easier to just use the most ConsistentCaseStyle everywhere and add a prefix ?
Fans of case insensitive languages care about code quality, they just want one style. Sometimes they accept the fact that one library is poorly written and use a strict style while the library might have no style or poor code.
Both case sensitive and insensitive languages require strict discipline, it makes more sense to have only one style everywhere. It would be better if we had a language that used only StrictCase, one style everywhere and prefixes.
There is a lot of poor C code, case sensitivity doesn't make it readable and you can't do anything about it. In a case insensitive language you could enforce a good style in your code without rewriting the library.
In a StrictCase language that doesn't exists yet, all code would have decent quality :)
MyClass myClass;
would be impossible with case-insensitive compiler.
Or you could be smart and actually use 2 different words... that better show what you are actually trying to do, like:
MyClass myCarDesign;
Duh.
There is another reason languages are case sensitive. IDs may be stored in a hash table and hash tables are dependent on hashing functions that will give different hashes for differing case. And it may not be convenient to convert all the IDs to all upper or all lower before running them through the hash function. I came across this issue when I was writing my own compiler. It was much simpler (lazier) to declare my language as case sensitive.
If word separation is not important then why do we put spaces between words? Therefore I think that underlines between words in a name do increase readability. Also lower case with Capitalization of appropriate characters is easiest to read. Lastly, it is surely much easier if all words can be conveyed by word of mouth - "Corporate Underscore Customer" rather than "Capital C Lower Case o r p o r a t e Underscore Capital C Lower Case u s t o m e r"! - the former can be spoken 'in one's head' the latter cannot - I wonder how people who are happy with case sensitivity handle these case sensitive names in their brains - I really struggle. So I feel that case sensitivity is not at all helpfull - a retrogade step from COBOL in my opinion.
Because people seriously overthink things.
Case insensitivity works best when it's also case-preserving and combined with a separation between type and variable namespaces. This means that:
If you declare a class as 'TextureImage' and then try to use it as 'textureImage', the IDE can autocorrect you. This gives you the advantage that you'll never have to hit the shift key unless you're declaring an identifier or using an underscore.
Just like in Java and several other languages; it's perfectly valid to type "MyClass myClass". The IDE and the compiler should have no problem differentiating between the use of a type and the use of a variable.
In addition, case insensitivity guarantees that 'o' and 'O' will never refer to different objects. Common arguments include:
"sOmEoNe wIlL tYpE cOdE lIkE tHiS"; => and that someone will _never_ be allowed to join a programming team, so this is a strawman argument. even if they did manage to do so, case insensitivity is more the solution than the problem, because it means that you don't have to remember whatever crazy uppercase/lowercase combination they use.
"you can't internationalize case insensitivity easily!"; => over 95% of programming languages are written in english for a very good reason. there are no competing character encodings and the vast majority of keyboards on earth are english based (in partial or whole). supporting unicode identifiers is perhaps the dumbest idea anyone has came up with in the 21st century; because a good portion of unicode characters are frikkin invisible surragates, reading code is hard enough without having to use google translate, and writing code is hard enough without having to copy-paste identifiers or use a character map.
"but case sensitive languages have more identifiers!"; => no, they have grammatically overloaded identifiers, which is substantially worse.
I don't use any case-insensitive languages, but the advantages are blatantly obvious if you think about this sort of thing seriously.
A reasonable answer might be that the designers of the language thought it
would make the language easier to understand thinking about the future :)