Suppose I have defined a function:
def hello(name:String, words:String) = println("Hello!" + name + words)
Then I defined a partial function:
def p = hello _
Print p, displayed:
(String, String) => Unit = <function2>
There's no function name displayed. Is it possible to get the original method name hello from the partial function p?
There has been some discussion on the mailing lists recently about a language construct that allows you to identify the current method that you're in. It would be called something like thisMethod and would essentially do for methods what this does for class instances.
I'd be interested to see how this interacts with functions (which are a different concept from methods). Your p is an anonymous function created from partially applying the hello method (again, you need to be careful here, a "partially applied function is a very different thing from a PartialFunction). The actual method then invoked would be apply on this function object, and there are several possibilities as to how thisMethod could behave in such a case.
Whatever happens, p is just an object reference, don't expect to ever be able to access it as a name.
No.
Its a feature I'd love to have, but it has serious conceptual problems like, what should happen, when the same function is given two names ... it should still be the same function, shouldn't it?
update in response to comment:
def p = hello _
def q = p
What is the name of q? p? or hello? or println? I have a hard time imagining a solution that is simple, consistent and usefull.
... that is actually a "partially applied function" that is created anonymously by calling your hello function without the parameters being applied. It does not have an explicit name to show.
Related
I'm a beginner of Scala who is struggling with Scala syntax.
I got the line of code from https://www.tutorialspoint.com/scala/higher_order_functions.htm.
I know (x: A) is an argument of layout function
( which means argument x of Type A)
But what is [A] between layout and (x: A)?
I've been googling scala function syntax, couldn't find it.
def layout[A](x: A) = "[" + x.toString() + "]"
It's a type parameter, meaning that the method is parameterised (some also say "generic"). Without it, compiler would think that x: A denotes a variable of some concrete type A, and when it wouldn't find any such type it would report a compile error.
This is a fairly common thing in statically typed languages; for example, Java has the same thing, only syntax is <A>.
Parameterized methods have rules where the types can occur which involve concepts of covariance and contravariance, denoted as [+A] and [-A]. Variance is definitely not in the scope of this question and is probably too much for you too handle right now, but it's an important concept so I figured I'd just mention it, at least to let you know what those plus and minus signs mean when you see them (and you will).
Also, type parameters can be upper or lower bounded, denoted as [A <: SomeType] and [A >: SomeType]. This means that generic parameter needs to be a subtype/supertype of another type, in this case a made-up type SomeType.
There are even more constructs that contribute extra information about the type (e.g. context bounds, denoted as [A : Foo], used for typeclass mechanism), but you'll learn about those later.
This means that the method is using a generic type as its parameter. Every type you pass that has the definition for .toString could be passed through layout.
For example, you could pass both int and string arguments to layout, since you could call .toString on both of them.
val i = 1
val s = "hi"
layout(i) // would give "[1]"
layout(s) // would give "[hi]"
Without the gereric parameter, for this example you would have to write two definitions for layout: one that accepts integers as param, and one that accepts string as param. Even worse: every time you need another type you'd have to write another definition that accepts it.
Take a look at this example here and you'll understand it better.
I also recomend you to take a look at generic classes here.
A is a type parameter. Rather than being a data type itself (Ex. case class A), it is generic to allow any data type to be accepted by the function. So both of these will work:
layout(123f) [Float datatype] will output: "[123]"
layout("hello world") [String datatype] will output: "[hello world]"
Hence, whichever datatype is passed, the function will allow. These type parameters can also specify rules. These are called contravariance and covariance. Read more about them here!
In the book of "functional programming in Scala", it gives some examples about side-effects, like:
Modifying a variable
Modifying a data structure in place
Setting a field on an object
Throwing an exception or halting with an error Printing to the console or reading user input
Reading from or writing to a file
Drawing on the screen
My question is, is reading some data from outside rathen than the parameters makes the function impure?
E.g.
val name = "Scala"
def upcase() = name.toUpperCase
Is the upcase function pure or not?
Edit: as per this answer: https://stackoverflow.com/a/31377452/342235, my "function" is not actually function, it's a method, so I give a function version of it, and ask the same question:
val name = "Scala"
val upcase: () => String = () => name.toUpperCase
Reading from immutable data is not impure; the function will still return the same value every time. If name were a var then that function would be impure, since something external could change name, so multiple calls to upcase() might evaluate to different values.
(Of course it might be possible to e.g. alter name through reflection. Properly we can only talk about purity with respect to some notion of what kind of functions are allowed to call a given function, and what kind of side effects we consider to be equivalent)
It's worth noting that your function is not pure because toUpperCase is not pure; it depends on the system's default Locale, and may produce different results on different systems (e.g. on a Turkish system, "i".toUpperCase == "İ"). You should always pass an explicit Locale, e.g. def upcase() = name.toUpperCase(Locale.ENGLISH); then the function will be pure.
Interestingly, the answer is "No", but not for the reason you think it is. Your upcase is not a pure function. It is, however, pure, but it is a method, not a function.
From my understanding, a partially applied function are functions, which we can invoke without
passing all/some of the required arguments.
def add(x:Int, y:Int) = x + y
val paf = add(_ :Int, 3)
val paf1 = add(_ :Int, _ :Int)
In the above example, paf1 refers to partially applied function with all the arguments missing and I can invoke is using: paf1(10,20) and the original function can be invoked using add(10,20)
My question is, what is the extra benefit of creating a partially applied function with all the arguments missing, since the invocation syntax is pretty much the same? Is it just to convert methods into first class functions?
Scala's def keyword is how you define methods and methods are not functions (in Scala). So your add is not a first-class function entity the way your paf1 is, even if they're semantically equivalent in what they do with their arguments in producing a result.
Scala will automatically use partial application to turn a method into an equivalent function, which you can see by extending your example a bit:
def add(x: Int, y: Int) = x + y
...
val pa2: (Int, Int) => Int = add
pa2: (Int, Int) => Int = <function2>
This may seem of little benefit in this example, but in many cases there are non-explicit constraints indicating a function is required (or more accurately, constraints specified explicitly elsewhere) that allow you to simply give a (type-compatible) method name in a place where you need a function.
There is a difference between Methods and functions.
If you look at the declaration of List.map for example, it really expects a function. But the Scala compiler is smart enough to accept both methods and functions.
A quote from here
this trick ... for coercing a method into something where a function is expected, is so easy that even the compiler can detect and do it. In fact, this automatic coercion got an own name – it’s called Eta expansion.
On the other hand, have a look at Java 8; as far as I can tell, it's not that easy there.
Update: the question was, Why would I ever want an eta-expanded method? One of the great rhetorical strategies in the Scala bible is that they lead you to an example over many pages. I employ the Exodus metaphor below because I just saw "The Ten Commandments" with Charlton Heston. I'm not pretending that this answer is more explanatory than Randall's.
You might need someone with lesser rep to note that the big build-up in the bible's book of Exodus is to:
http://www.artima.com/pins1ed/first-steps-in-scala.html#step6
args foreach println.
The previous step among the "first steps" is, indeed,
args foreach (arg => println(arg))
but I'm guessing no one does it that way if the type inference gods are kind.
From the change log in the spec: "a partially unapplied method is now designated m _ instead
of the previous notation &m." That is, at a certain point, the notion of a "function ptr" became a partial function with no args supplied. Which is what it is. Update: "metaphorically."
I'm sure others can synthesize a bunch of use-cases for this, but really it's just a consequence of the fact that functions are values. It would be much weirder if you couldn't pass a function around as a normal value.
Scala's handling of this stuff is a little clunky. Partial application is usually combined with currying. I consider it a quirk that you can basically eta-expand any expression using _. What you're effectively doing (modulo Scala's syntactic quirks around currying) by writing add(_ : Int, _ : Int) is writing (x : Int) => (y : Int) => add(x, y). I'm sure you can think of instances where the latter definition might be useful in a program.
I've been working on learning the ins and outs of scala, and recently I've come across something I'm curious about.
As I understand, if I want to pass a block of code that is effectively lazily evaluated to a function, (without evaluating it on the spot) I could type:
def run(a: =>Int):Int = {...}
In this sense, the function run receives a block of code, that is yet to be evaluated, which it evaluates and returns the computed Int of. I then tried to extend this idea to the List data structure. Typing:
def run(a: List[=>Int]) = {...}
This however, returns an error. I was wondering why this is disallowed. How, other than by this syntax can I pass a list of unevaluated blocks of code?
=>Int is the syntax for by name parameters. =>Int is not a type, so it can't be used as a parameter to List. However, ()=>Int is a type. It's the type of nullary functions that return Int. So this works:
def run(a: List[()=>Int]) = {...}
by-name parameter is not a first-class type in Scala.
List[()=>Int] is one of the solution. otherwise, You can use following Lazy data structure.
https://gist.github.com/1164885
https://github.com/scalaz/scalaz/blob/v6.0.4/core/src/main/scala/scalaz/Name.scala#L99-107
https://github.com/scalaz/scalaz/blob/v7.0.0-M7/core/src/main/scala/scalaz/Name.scala#L37-L60
https://github.com/scala/scala/blob/v2.10.0/src/reflect/scala/reflect/internal/transform/Transforms.scala#L9-23
https://github.com/harrah/xsbt/blob/v0.12.1/compile/api/SafeLazy.scala
https://github.com/okomok/ken/blob/0.1.0/src/main/scala/com/github/okomok/ken/Lazy.scala
https://github.com/playframework/Play20/blob/2.1-RC1/framework/src/play/src/main/scala/play/api/libs/functional/Util.scala#L3-L11
I'm a relative Scala beginner and would like some advice on how to proceed on an implementation that seems like it can be done either with a function returning Option or with PartialFunction. I've read all the related posts I could find (see bottom of question), but these seem to involve the technical details of using PartialFunction or converting one to the other; I am looking for an answer of the type "if the circumstances are X,Y,Z, then use A else B, but also consider C".
My example use case is a path search between locations using a library of path finders. Say the locations are of type L, a path was of type P and the desired path search result would be an Iterable[P]. The patch search result should be assembled by asking all the path finders (in something like Google maps these might be Bicycle, Car, Walk, Subway, etc.) for their path suggestions, which may or may not be defined for a particular start/end location pair.
There seem to be two ways to go about this:
(a) define a path finder as f: (L,L) => Option[P] and then get the result via something like finders.map( _.apply(l1,l2) ).filter( _.isDefined ).map( _.get )
(b) define a path finder as f: PartialFunction[(L,L),P] and then get the result via something likefinders.filter( _.isDefined( (l1,l2) ) ).map( _.apply( (l1,l2)) )`
It seems like using a function returning Option[P] would avoid double evaluation of results, so for an expensive computation this may be preferable unless one caches the results. It also seems like using Option one can have an arbitrary input signature, whereas PartialFunction expects a single argument. But I am particularly interested in hearing from someone with practical experience about less immediate, more "bigger picture" considerations, such as the interaction with the Scala library. Would using a PartialFunction have significant benefits in making available certain methods of the collections API that might pay off in other ways? Would such code generally be more concise?
Related but different questions:
Inverse of PartialFunction's lift method
Is the PartialFunction design inefficient?
How to convert X => Option[R] to PartialFunction[X,R]
Is there a nicer way of lifting a PartialFunction in Scala?
costly computation occuring in both isDefined and Apply of a PartialFunction
It's not all that well known, but since 2.8 Scala has a collect method defined on it's collections. collect is similar to filter, but takes a partial function and has the semantics you describe.
It feels like Option might fit your use case better.
My interpretation is that Partial Functions work well to be combined over input ranges. So if f is defined over (SanDiego,Irvine) and g is defined over (Paris,London) then you can get a function that is defined over the combined input (SanDiego,Irvine) and (Paris,London) by doing f orElse g.
But in your case it seems, things happen for a given (l1,l2) location tuple and then you do some work...
If you find yourself writing a lot of {case (L,M) => ... case (P,Q) => ...} then it may be the sign that partial functions are a better fit.
Otherwise options work well with the rest of the collections and can be used like this instead of your (a) proposal:
val processedPaths = for {
f <- finders
p <- f(l1, l2)
} yield process(p)
Within the for comprehension p is lifted into an Traversable, so you don't even have to call filter, isDefined or get to skip the finders without results.