How to recursively take the last argument of a macro? - macros

Using a simple recursive macro like the example below, its common to take the first argument, then glob the rest.
macro_rules! count_tts {
() => {0usize};
($_head:tt $($tail:tt)*) => {1usize + count_tts!($($tail)*)};
}
Is there a way to recursively take the last argument?
This makes it possible to:
Handle the arguments in reverse.
Take all the previous arguments into account (count them for example, see related question)
Something like ($($head:tt)* $tail:tt) ... but this doesn't work.

There is no "backtracking" in the macro parser, so no you can't do this directly with $($head:tt)* $tail:tt. But you can do it by reversing it yourself.
macro_rules! concat_reverse {
([] $($reversed:tt)*) => {
concat!($(stringify!($reversed)),*) // base case
};
([$first:tt $($rest:tt)*] $($reversed:tt)*) => {
concat_reverse!([$($rest)*] $first $($reversed)*) // recursion
};
}
fn main() {
println!("{}", concat_reverse!([e d c b a]))
// output: abcde
}
The macro trace looks like:
concat_reverse!([e d c b a])
== concat_reverse!([d c b a] e)
== concat_reverse!([c b a] d e)
== concat_reverse!([b a] c d e)
== concat_reverse!([a] b c d e)
== concat_reverse!([] a b c d e)
== concat!(stringify!(a), stringify!(b), stringify!(c), stringify!(d), stringify!(e))
You could do some "map" and "reduce" operation (e.g. for counting) in the recursion phase.
Note that this method will eat your recursion depth, you may need to raise your #![recursion_limit="..."].

Related

Why this code compiles and it gives runtime error when it executes

This Scala code compiles under Scala 2.13
val res = new scala.collection.mutable.StringBuilder
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( res += c )
}
}
If you see the foreach method is missing argument for anonymous function. When it is executed it gives an exception StringIndexOutOfBoundsException for res += c which is puzzling since StringBuilder should always be appendable.
Following code runs fine and there are no exceptions. The only change is adding _ as placeholder for foreach parameter function:
val res = new scala.collection.mutable.StringBuilder()
"hello".foreach { c =>
if (true) {
(0 until 10).foreach( _ => res += c )
}
}
The answer to your question lies in String.apply() or StringBuilder.apply() to be more exact.
You see, foreach expects a function. In more exact words, an expression which evaluates to a function.
So, it will first evaluate the expression to get the function then it will apply that function for 0 until 10
so when you consider the first iteration of outer foreach, you have c = 'h' and following,
(0 until 10).foreach(res += c )
Here, res += c will return res after appending h to it.
So... the evaluated function is res or res.apply with res = "h". Hence, the above is actually,
(0 until 10).foreach("h".apply)
So, res.apply(0) goes well... but res.apply(1) fails with StringIndexOutOfBoundsException.
Please see the signature for
def foreach[U](f: A => U): Unit = {
}
(f: A => U) this is a function, not an expression.

Working with strings and objects

I think my problem is pretty straight forward - I have a text file made out of 'E' and 'B' symbols, for example:
EBBEBBB BBEB
E
BEB BEB B
B
Now i want to get this data. When i use it, i don't want it to be in a form of strings because you can pass anything that would not work, for example something like a number or any other invalid symbol. That's why i figured i could create some case objects that extends a single trait(like shown below). Problem is, I don't know how i should CORRECTLY convert my string data to that particular data structure that I made:
sealed trait EB
case object E extends EB
case object B extends EB
case class EB_Text(data: Vector[EB])
def convertText(fileData: Vector[String]) : EB_Text = {
//Match each symbol and check if it's 'E' or 'B' ?
//If i find an invalid symbol here, what do i return? Should i return AN Option here?
}
Thank you! ^^
You can construct the function in the following way
def convertText(fileData: Vector[String]) : EB_Text = {
EB_Text(fileData.map{
singleLine =>
singleLine.replaceAll(" ","").toUpperCase().collect{
case 'E' => E
case 'B' => B
}
}.flatten)
}
You do not need to make any modifications to the case objects that you had defined earlier. You can keep them as it is
sealed trait EB
case object E extends EB
case object B extends EB
case class EB_Text(data: Vector[EB])
On invoking the function with the following input, you will get the output as
val input = Vector("EBBEBBB BBEB"," E","BEB BEB B"," B ")
convertText(input)
you will get the output as
res0: EB_Text = EB_Text(Vector(E, B, B, E, B, B, B, B, B, E, B, E, B, E, B, B, E, B, B, B))
I hope this answers your question.
Your logic is correct and returning an options sounds like the right thing to do. If you don't need the option though (or any other information related to the convert operation, e.g. the underlying string) there is no reason to construct it.
I also don't think that is necessary to wrap the result in a case class.
def convertText(fileData: Vector[String]) : Vector[EB] = {
for (s <- fileData if s == "E" || s == "B") yield {
if (s == "E") E
else B
}
}

Scala placeholder behavior

Suppose l = List(1, 2, 3):
scala> l foreach { println _ }
1
2
3
scala> l foreach { println }
1
2
3
l foreach { println _ } <=> l foreach { println } because _ can be omitted. But why does the following also produces the same result?
scala> l foreach { println(_) }
1
2
3
Shouldn't the _ be bounded to println instead of foreach?
in other words:
l foreach { println(_) } <=> l foreach { println(x => x) }
and therefore throws an error on missing parameter type?
l foreach { println(_.toString) } produces the expected missing parameter type error
foreach takes a function A => Unit, in this case, Int => Unit
println satisfies this condition, but it is a method, not a function. Scala can get around this though, through a technique called eta expansion. It creates a function that takes the inputs for the method and called the method with those inputs. In your case, it looks similar to (x: Int) => println(x).
Each way you've written accomplishes this.
l foreach { println }
Here Scala is able to infer that you want to treat println as a function and pass it to foreach
l foreach { println _ }
By adding the underscore you explicitly saying that you want to turn the method into a function
l foreach { println(_) }
This is similar to the last, for any method you call, you can use an underscore instead of passing a parameter. By doing this, instead of calling the method you create a partially-applied function. You then pass this function to foreach
l foreach { println(_.toString) }
This is quite a bit different. _.toString creates a function A => String but Scala cannot figure out the correct type for A. Another problem is not you are passing a value to println, so you are calling println and passing the result to foreach instead of turning it into a function. println returns Unit which is the wrong type to pass to foreach
Shouldn't the _ be bounded to println instead of foreach? in other words:
l foreach { println(_) } <=> l foreach { println(x => x) }
No, this is specifically excluded by rules for placeholders in anonymous functions:
An expression e of syntactic category Expr binds an underscore section u, if the following two conditions hold: (1) e properly contains u, and (2) there is no other expression of syntactic category Expr which is properly contained in e and which itself properly contains u.
"Properly contains" means _ never binds itself, and so it never expands to x => x. In your last example, _.toString does properly contain _ and so satisfies both conditions above.
You're forgetting that println(x) can also be written as println x in Scala. If there's only a single argument, the parenthesis are optional.

Is there a concept for 'fold with break' or 'find with accumulator' in functional programming?

Title says it all, really; iterating over collection while preserving state between loops and finishing iteration based on termination condition in addition to simply running out of elements may be the most common pattern to accomplish anything in imperative programming. It seems to me however like it's something functional gentleprogrammers agreed to not talk about, or at least I never encountered an idiom for it or a semi-standarized name such as with map, fold, reduce, etc.
I often use the followinig code in scala:
implicit class FoldWhile[T](private val items :Iterable[T]) extends AnyVal {
def foldWhile[A](start :A)(until :A=>Boolean)(op :(A, T)=>A) :A = {
if (until(start)) start
else {
var accumulator = start
items.find{ e => accumulator = op(accumulator, e); until(accumulator) }
accumulator
}
}
}
But it's ugly. Whenever I try a more declarative approach, I come with even longer and almost surely slower code, akin to:
Iterator.iterate((start, items.iterator)){
case (acc, i) if until(acc) => (acc, i)
case (acc, i) if i.hasNext => (op(acc, i.next()), i)
case x => x
}.dropWhile {
case (acc, i) => !until(acc) && i.hasNext
}.next()._1
(A more functional variant would use Lists or Streams, but iterators have arguably lesser overhead than converting items to a Stream, as default implementation for the latter uses an iterator underneath anyway).
My questions are:
1) Does this concept have a name in functional programming, and if so, what is the pattern associated with its implementation?
2) What would be the best (i.e. concise, generic, lazy, and with least overhead) way to implememnt it in scala?
This is frowned upon by scala purists, but you can use a return statement like this:
def foldWhile[A](zero: A)(until:A => Boolean)(op: (A,T) => A): A = items.fold(zero) {
case (a, b) if until(a) => return a
case (a,b) => op(a, b)
}
Or, if you are one of those frowning, and would like a purely functional solution without dirty imperative tricks, you can use something lazy, like an iterator or a stream:
items
.toStream // or .iterator - it doesn't really matter much in this case
.scanLeft(zero)(op)
.find(until)
The functional way of doing such things is via Tail Recursion:
implicit class FoldWhile[T](val items: Iterable[T]) extends AnyVal {
def foldWhile[A](zero: A)(until: A => Boolean)(op: (A, T) => A): A = {
#tailrec def loop(acc: A, remaining: Iterable[T]): A =
if (remaining.isEmpty || !until(acc)) acc else loop(op(acc, remaining.head), remaining.tail)
loop(zero, items)
}
}
Using recursion you can decide at each step if you want to proceed or not without using break and without any overhead, because tail recursions are converted to iterations from the compiler.
Also, pattern matching is often used to decompose sequences. For example, if you had a List you could do:
implicit class FoldWhile[T](val items: List[T]) extends AnyVal {
def foldWhile[A](zero: A)(until: A => Boolean)(op: (A, T) => A): A = {
#tailrec def loop(acc: A, remaining: List[T]): A = remaining match {
case Nil => acc
case _ if !until(acc) => acc
case h :: t => loop(op(acc, h), t)
}
loop(zero, items)
}
}
Scala has the #scala.annotation.tailrec annotation to force compilation to fail if the function you're annotating is not tail recursive. I suggest you use it as much as you can because it helps both to avoid errors and document the code.
The functional name for this is an Iteratee.
There are a bunch of references about this, but it's probably better to start from where the design ended up by reading the Pipes Tutorial and only if you're interested working backwards from there to see how it came from an early terminating left fold.
A right fold, when done lazily, can do early termination. In Haskell, for example, you can write the find function (return first element of list that satisfies predicate) with foldr:
find :: (a -> Bool) -> [a] -> Maybe a
find p = foldr (\a r -> if p a then Just a else r) Nothing
-- For reference:
foldr :: (a -> r -> r) -> r -> [a] -> r
foldr _ z [] = []
foldr f z (a:as) = f a (foldr f z as)
What happens when you try, say, find even [1..]? (Note that this is an infinite list!)
find even [1..]
= foldr (\a r -> if even a then Just a else r) Nothing [1..]
= if even 1
then Just 1
else foldr (\a r -> if even a then Just a else r) Nothing ([2..])
= if False
then Just 1
else foldr (\a r -> if even a then Just a else r) Nothing ([2..])
= foldr (\a r -> if even a then Just a else r) Nothing ([2..])
= if even 2
then Just 2
else foldr (\a r -> if even a then Just a else r) Nothing ([3..])
= if True
then Just 2
else foldr (\a r -> if even a then Just a else r) Nothing ([3..])
= Just 2
Laziness means that the function that we fold with (\a r -> if even a then Just a else r) gets to decide whether to force the r argument—the one whose evaluation requires us to recurse down the list—at all. So when even 2 evaluates to True, we pick the branch of the if ... then ... else ... that discards the result computed off the tail of the list—which means we never evaluate it. (It also runs in constant space as well. While programmers in eager functional languages learn to avoid foldr because of space and termination issues, those aren't always true in lazy languages!)
This of course hinges on the fact that Haskell is lazily evaluated, but it should nevertheless be possible to simulate this in an eager language like Scala—I do know it has a lazy val feature that might be usable for this. It looks like you'd need to write a lazyFold function that does a right fold, but the recursion happens inside a lazy value. You might still have problems with space usage, though.

InputRange Concatenation

Is there a higher-order range pattern that concatenates two or more InputRanges?
Something like
foreach (e; a) {
// do stuff with e
}
foreach (e; b) {
// do stuff with e
}
...
should instead be written as
foreach (e; someMagic(a, b, ...)) {
// do stuff with e
}
someMagic is chain from std.range: http://dlang.org/phobos/std_range.html#chain