I've coded an experimental function which makes passed objects chainable by using high order functions. It's name is "chain" for now, and here is a usage example;
chain("Hello World")
(print) // evaluates print function by passing "Hello World" object.
(console.log,"Optional","Parameters")
(returnfrom) // returns "Hello World"
It looks lispy but behaves very different since it's coded in a C based language, I don't know if there is a name for this idiom and I couldn't any name more suitable than "chain".
Any ideas, suggestions?
edit: "with" sounds very suitable name but it's a reserved word in the language I'm working on.
This API design pattern is usually called a Fluent interface.
Update: Whether the actual implementation of a fluent interface is in object-oriented language is irrelevant. It's the pattern of passing a context to achieve the feeling of a "code flow", which seems exactly what you are aiming to do.
Of course, what the pattern name is does not actually answer your question. :-)
As you noted, the best choice for naming your actual function would be with. Second best would be using.
Related
I'm confused by Data.Map API. I'm looking for a simple way to find a range of keys of the map at log(n) cost. This is a basic concept known as "binary search", and maybe "bisecting".
I see this strange takeWhileAntitone function where I need to provide an "antitone" predicate function. It's the first time I encounter this concept.
After reading Wikipedia on the topic, this seems to be simply saying that there may be only one place where the function changes from True to False when applied to arguments in key order. This fits a requirement for a binary search.
Since the API is documented in a strange (to me) language, I wanted to ask here:
if my understanding is correct, and
is there a reason these functions aren't called bisect, binarySearch or similar?
Since the API is documented in a strange (to me) language, I wanted to ask here:
if my understanding is correct, and
Yes. takeWhileAntitone (and other similarly named variants in the library) is the function for doing binary search on keys. It's not named takeWhile because it does not work for any argument predicate, so if you're reviewing code, it serves as a reminder to check for that.
is there a reason these functions aren't called bisect, binarySearch or similar?
This name serves to distinguish variants takeWhileAntitone, dropWhileAntitone, spanAntitone that "do binary search" but with different final results.
takeWhile is a well-known name from Haskell's standard library (in Data.List).
In FP we like to distinguish the "what" from the "how". "binary search" is an algorithm ("how"). "take while" is also literally a "how", but its meaning is arguably more naturally connected to a "what" (the longest prefix of elements satisfying a predicate). In particular, the interpretation of "take while" as "longest prefix" doesn't rely on any assumption about the predicate.
I am writing my first R package and I am trying to figure out what the best way to assign values to a slot in an S4 object, keeping in mind that end-users shouldn't have to fuss with the details of the S4 class structures being used. Which of the following is best?
Accessing slot directly using object#MySlot <- value:
I understand that this bad practice (e.g., this Q&A).
Using slot(object, "MySlot") <- value:
The R help says there isn't checking when getting the values, but there is checking when setting (assuming check hasn't been set to FALSE). This sounds reasonable to me, and strikes me as a nice way to do it because I don't have to code my own get/set methods as per below.
Using custom methods with setReplaceMethod():
How does this approach compare against the second option above? It's more work to produce the necessary get/set methods, but I can more explicitly be sure that the values being written to the slots are valid for that slot type.
setGeneric("MySlot", function(object) {
standardGeneric("MySlot")
})
setMethod("MySlot",
signature = "MyClass",
definition = function(object) {
return(object#MySlot)
})
setGeneric("MySlot<-",
function(object, value) {
standardGeneric("MySlot<-")
})
setReplaceMethod("MySlot",
signature="MyClass",
function(object, value) {
object#MySlot<- value
validObject(object) # could add other checks
return(object)
})
By definition, "not having to fuss with the details of the S4 class structure" means end-users should not have to know about your slots. As such, any wrappers you write as in steps 2 and 3 are more for internal consistency checks. I think more important is to check for edge cases where you think your integrity checks would fail using unit tests.
As you have pointed out, #1 can be ruled out fairly easily, and should only be used in internal methods. Whether you encourage #2 or implement #3 depends on the contents of the variable and personal taste, but I would encourage the latter. For example, if you have a logical flag, you can use #2, but more descriptive would be enableFoo(). That being said, if you have to consider developer time (which in real life is almost always true) you should think briefly about the trade-off between relegating mutators to slot<- for members that probably won't be accessed frequently (e.g., by less than 1% of users), versus implementing custom mutators for everything as in #3.
Finally, since almost all three of R's OOP systems are essentially syntactic sugar and aren't really respected semantically by the language (where only S4 can claim some exception), it is easy to forget the fundamental ideas behind object-oriented programming as implemented in other languages: any code executing outside of your methods should not know about the object's members. You are providing an external interface to the world that is and should be a black box.
I'm trying to get my head around a core concept of functional langauges:
"A central concept in functional languages is that the result of a function is determined by its input, and only by its input. There are no side-effects!"
http://www.haskell.org/haskellwiki/Why_Haskell_matters#Functions_and_side-effects_in_functional_languages
My question is, if a function makes changes only within its local environment, and returns the result, how can it interact with a database or a file system? By definition, wouldn't that be accessing what is in effect a global variable or global state?
What is the most common pattern used to get around or address this?
Just because a functional language is functional (Maybe even completely pure like Haskell!), it doesn't mean that programs written in that language must be pure when ran.
Haskell's approach, for example, when dealing with side-effects, can be explained rather simply: Let the whole program itself be pure (meaning that functions always return the same values for the same arguments and don't have any side effect), but let the return value of the main function be an action that can be ran.
Trying to explain this with pseudocode, here is some program in an imperative, non-functional language:
main:
read contents of abc.txt into mystring
write contents of mystring to def.txt
The main procedure above is just that: a series of steps describing how to perform a series of actions.
Compare this to a purely functional language like Haskell. In functional languages, everything is an expression, including the main function. One can thus read the equivalent of the above program like this:
main = the reading of abc.txt into mystring followed by
the writing of mystring to def.txt
So, main is an expression that, when evaluated, will return an action describing what to do in order to execute the program. The actual execution of this action happens outside of the programmers world. And this is really how it works; the following is an actual Haskell program that can be compiled and ran:
main = readFile "abc.txt" >>= \ mystring ->
writeFile "def.txt" mystring
a >>= b can be said to mean "the action a followed by the result of a given to action b" in this situation, and the result of the operator is the combined actions a and b. The above program is of course not idiomatic Haskell; one can rewrite it as follows (removing the superfluous variable):
main = readFile "abc.txt" >>=
writeFile "def.txt"
...or, using syntactic sugar and the do-notation:
main = do
mystring <- readFile "abc.txt"
writeFile "def.txt" mystring
All of the above programs are not only equivalent, but they are identical as far as the compiler is concerned.
This is how files, database systems, and web servers can be written as purely functional programs: by threading action values through the program so that they are combined, and finally end up in the main function. This gives the programmer enormous control over the program, and is why purely functional programming languages are so appealing in some situations.
The most common pattern for dealing with side-effects and impurity in functional languages is:
be pragmatic, not a purist
provide built-ins that allow impure code and side-effects
use them as little as possible!
Examples:
Lisp/Scheme: set!
Clojure: refs, and using mutating methods on java objects
Scala: creating variables with var
ML: not sure of specifics, but Wikipedia says it allows some impurity
Haskell cheats a little bit -- its solution is that for functions that access the file system, or the database, the state of the entire universe at that instant, including the state of the filesystem/db, will be passed in to the function.(1) Thus, if you can replicate the state of the entire universe at that instant, then you can get the same results twice from such a function. Of course, you can't replicate the state of the entire universe at that instant, and so the functions return different values ...
But Haskell's solution, IMHO, is not the most common.
(1) Not sure of the specifics here. Thanks to CAMcCann for pointing out that this metaphor is overused and maybe not all that accurate.
Acessing a database is no different from other cases of input-output, such as print(17).
In eagerly evaluated languages, like LISP and ML the usual approach to effectful programming is just using side effects, like in most other programming languages.
In Haskell, the solution for the IO problem is using monads. For example, if you check HDBC, a haskell database library, you can see lots of functions there return IO actions.
Some languages, like Clean, use uniqueness-types to enforce the same kind of sequentiality Haskell does with monads but these languages are harder to find nowadays.
In Chapter 3, There is an example called "MySecond.hs", what I really don't understand is code like this:
safeSecond :: [a] -> Maybe a
it always in the first line of file, and delete it causes no trouble. anyone could enlight me with what that means? I am but a newbie to any functional programming language.
It is the type annotation. If you don't write it Haskell will infer it.
In this case safeSecond is the name of something. The :: separates the name from the type. It takes a list of type a(a is a type variable this function will work on a list of any type.) -> is function application, and Maybe a is the return type.
Note that 'a' represents a single type so if you pass in a int list you must get a Maybe int out. That is to say all 'a's in the the type must agree.
Maybe is just a type that has two alternatives Just a or Nothing.
It's the type signature of the function. It's meant to show what the inputs and outputs of the function are supposed/expected to be. For most Haskell code the compiler can infer it if you don't specify it, but it is highly recommended to always specify it.
Aside from helping you remember what the function should actually do, it's also a nice way for others to get an idea about what the function does.
Besides that, it's also useful for debugging, for instance when the type of the function isn't what you expected it to be. If you have a type signature for that function, you would get an error at the definition site of the function, vs if you don't you'd get one at the call site. see Type Signatures and Why use type signatures
Also since you're reading RWH, Chapter 2 covers this.
This is a type annotation; it acts like a function declaration in C.
In Haskell, type declaration is usually not strictly necessary, as Haskell can usually infer a good type from correct code. However, it is generally a good idea to declare types for important values, because:
If your code is not correct, you tend get more useful error messages that way (otherwise the compiler can get confused trying to infer your types, and the resulting failure message may not be clearly related to the actual error). If you are getting obscure/verbose error messages, adding type annotation may improve them.
Especially as a beginner, declaring important types can make you less confused about what you're doing -- it forces you to clarify your thinking as you write the program.
As others have mentioned, type annotation acts as active documentation, making other people less confused about your code. As usual, "other people" may be you, a few months down the road.
Generally speaking, creating a fluid API is something that makes all programmers happy; Both for the creators who write the interface, and the consumers who program against it. Looking beyond conventions, why is it that we prefix all our getters with the word "get". Omitting it usually results in a more fluid, easy to read set of instructions, which ultimately leads to happiness (however small or passive). Consider this very simple example. (pseudo code)
Conventional:
person = new Person("Joey")
person.getName().toLower().print()
Alternative:
person = new Person("Joey")
person.name().toLower().print()
Of course this only applies to languages where getters/setters are the norm, but is not directed at any specific language. Were these conventions developed around technical limitations (disambiguation), or simply through the pursuit of a more explicit, intentional feeling type of interface, or perhaps this is just a case of trickle a down norm. What are your thoughts? And how would simple changes to these conventions impact your happiness / daily attitudes towards your craft (however minimal).
Thanks.
Because, in languages without Properties, name() is a function. Without some more information though, it's not necessarily specific about what it's doing (or what it's going to return).
Functions/Methods are also supposed to be Verbs because they are performing some action. name() obviously doesn't fit the bill because it tells you nothing about what action it is performing.
getName() lets you know without a doubt that the method is going to return a name.
In languages with Properties, the fact that something is a Property expresses the same meaning as having get or set attached to it. It merely makes things look a little neater.
The best answer I have ever heard for using the get/set prefixes is as such:
If you didn't use them, both the accessor and mutator (getter and setter) would have the same name; thus, they would be overloaded. Generally, you should only overload a method when each implementation of the method performs a similar function (but with different inputs).
In this case, you would have two methods with the same name that peformed very different functions, and that could be confusing to users of the API.
I always appreciate consistent get/set prefixing when working with a new API and its documentation. The automatic grouping of getters and setters when all functions are listed in their alphabetical order greatly helps to distinguish between simple data access and advanced functinality.
The same is true when using intellisense/auto completion within the IDE.
What about the case where a property is named after an verb?
object.action()
Does this get the type of action to be performed, or execute the action... Adding get/set/do removes the ambiguity which is always a good thing...
object.getAction()
object.setAction(action)
object.doAction()
In school we were taught to use get to distinguish methods from data structures. I never understood why the parens wouldn't be a tipoff. I'm of the personal opinion that overuse of get/set methods can be a horrendous time waster, and it's a phase I see a lot of object oriented programmers go through soon after they start.
I may not write much Objective-C, but since I learned it I've really come to love it's conventions. The very thing you are asking about is addressed by the language.
Here's a Smalltalk answer which I like most. One has to know a few rules about Smalltalk BTW.
fields are only accessible in the they are defined.If you dont write "accessors" you won't be able to do anything with them.
The convention there is having a Variable (let's anme it instVar1.
then you write a function instVar1 which just returns instVar1 and instVar: which sets
the value.
I like this convention much more than anything else. If you see a : somewhere you can bet it's some "setter" in one or the other way.
Custom.
Plus, in C++, if you return a reference, that provides potential information leakage into the class itself.