News for hackers. Stuff that matters.
Re:Streem – a new programming language from Matz by c3RlcGhlbnI_ on Thursday December 11, 2014 @01:32PM (#8736315)
I am glad that someone is working on a new stream processing language, it is a very interesting paradigm. However I hope that they provide some very robust tools for controlling input splitting. As I have spent too much time fighting with awk and wishing it was more flexible(it is frustrating always having exactly two levels of splitting with only matchers on the first and only inverse splitting on the second).

As is you would have to put in filters to resplit input into lines and that is very messy for something that you will need/want to do very often.

For example if you wanted to parse by character it would be wonderful to be able to do the following:

  STDIN | /./{|c|
    # stuff
  }
Even better would be if you took it a step further and offered something like regex pattern matching for the block input. e.g.

  STDIN | /\w+/{|word|
    /house/ {
      # when word is house
    }
    /car/ {
      # when word is car
    }
    {
      # default case
    }
  }
Re:Streem – a new programming language from Matz by mackwic on Thursday December 11, 2014 @02:24PM (#8736589)
Awesome ! Let's call it sed !

Reference: https://www.gnu.org/software/sed/manual/sed.html#Examples

Sorry, I couldn't miss that one. :) Really, check the example. Sed is most powerful tool and can do astonishing work.

Re:Streem – a new programming language from Matz by c3RlcGhlbnI_ on Thursday December 11, 2014 @03:20PM (#8736859)
That manual is possibly the single most useful technical document that I have ever read. It has enabled me to write extremely powerful programs that no one I know can understand.

It would however be nice to have a tool with similar power but simpler, more comprehensible syntax. One of the other commenters linked to an interesting document on sam, which has a better control flow but equally arcane syntax.

Re:Streem – a new programming language from Matz by kbenson on Thursday December 11, 2014 @03:41PM (#8736949)
I think I could argue that Perl is that tool. I'm not looking forward to people chiming in about the syntax that have little to no experience with it though.
Re:Streem – a new programming language from Matz by SiVal on Thursday December 11, 2014 @07:53PM (#8738000)
I fell in love with Perl 3 over twenty years ago and loved how it took the best parts of both awk and sed and added extra features while making the overall syntax more consistent. Ironically, the consistency of Perl's syntax in those days (vs having to remember awk, sed, and other somewhat overlapping tools, each with its own awkward syntax) made it an amazingly convenient super-tool for stream processing. Perl 4 came along almost immediately, and I couldn't believe how powerful those little "Perl one-liners" could be.

With Perl 5, Perl essentially repositioned itself as a full-blown, general-purpose programming language, with all the power that entailed, but still stuck with a syntax based on essentially trying to be a more powerful and consistent superset of sed and awk.

These days, I think we could do a lot better with a stream processor with the stream-processing focus and one-liner power of Perl 4 but without the needless (these days) constraint of retaining the syntactic hash of ancient unix utilities.

Re:Streem – a new programming language from Matz by drinchev on Thursday December 11, 2014 @04:41PM (#8737200)
Perl indeed. I know there are a lot of modern compilers out there, but speaking about parsing files I think perl suits me the most in terms of code readability/speed balance.
Re:Streem – a new programming language from Matz by candu on Thursday December 11, 2014 @09:22PM (#8738304)
> It has enabled me to write extremely powerful programs that no one I know can understand.

I'd argue that makes it one of the least useful documents you've ever read :)

Re:Streem – a new programming language from Matz by gadders on Friday December 12, 2014 @05:02AM (#8739305)
> It has enabled me to write extremely powerful programs that no one I know can understand.

A job for life! :-)

Re:Streem – a new programming language from Matz by mackwic on Thursday December 11, 2014 @03:35PM (#8736923)
I think that stream-oriented languages are doomed to have an arcanic syntax.

Streams are a non-trivial construction, after all.

Re:Streem – a new programming language from Matz by marvy on Thursday December 11, 2014 @04:16PM (#8737104)
I think I don't believe you. Look at the car and house example above. Is that arcane?
Re:Streem – a new programming language from Matz by mackwic on Thursday December 11, 2014 @06:11PM (#8737601)
Well, sorry but sed _is_ cryptic. Let me quote an exemple for you (squeezing blank lines):

>leaves a blank line at the beginning and end if there are some already.

     #!/usr/bin/sed -f

     # on empty lines, join with next 
     # Note there is a star in the regexp 
     :x 
     /^\n*$/ { 
       N
       bx
     }
     
     # now, squeeze all '\n', this can be also done by:
     # s/^\(\n\)*/\1/
     s/\n*/\
     /
As soon as you begin to use sed registers, the code becomes arcanic.
Re:Streem – a new programming language from Matz by balakk on Friday December 12, 2014 @12:10AM (#8738664)
> arcanic

Arcane. Some would call it archaic too :)

Re:Streem – a new programming language from Matz by mijoharas on Friday December 12, 2014 @09:26AM (#8740118)
> I think that stream-oriented languages are doomed to have an arcanic syntax.

> Streams are a non-trivial construction, after all.

...

> Well, sorry but sed _is_ cryptic. Let me quote an exemple for you (squeezing blank lines):

I agree with you that sed is cryptic, but I don't think that that necessarily means that stream processing languages are doomed to have an archaic syntax. I'd also agree with marvy in saying that the car and house example is very clear as to it's intent:

  STDIN | /\w+/{|word|
      /house/ {
        # when word is house
      }
      /car/ {
        # when word is car
      }
      {
        # default case
      }
    }
I'd say that's very straightforward and not arcane at all. Just because sed is arcane (it could be argued) doesn't make it a precondition for any stream language

EDITS: formatting.

Re:Streem – a new programming language from Matz by GFK_of_xmaspast on Thursday December 11, 2014 @03:07PM (#8736792)
Everything you can do in sed you can do in perl, there's been sed-to-perl converters shipped with perl since the ur-times.
Re:Streem – a new programming language from Matz by mackwic on Thursday December 11, 2014 @03:37PM (#8736933)
Yeah yeah, of course. The hacked syntax showed by GP made me really think of sed. :)
Re:Streem – a new programming language from Matz by nateabele on Thursday December 11, 2014 @01:38PM (#8736355)
> However I hope that they provide some very robust tools for controlling input splitting

Yes, splitting and combining. Looking at the code example, I feel like so much opportunity is just being squandered, where something like Rust's mapping constructs would feel so much better. Yours is definitely more in that vein, here's something a little closer:

  STDIN | /\w+/{|word|
    /house/   => "foo"
    /car/     => "bar"
    "literal" => "baz"
    _         => "dib"
    # (where _ is a magical symbol for the default case... could be anything)
  }
Re:Streem – a new programming language from Matz by rudolf0 on Thursday December 11, 2014 @01:59PM (#8736456)
Streaming, pattern matching, and regex combined in one sounds pretty damn cool.

Might also be nice to borrow some of Scala's features for terser code than Ruby, like

    ary | { _ + 5 }
instead of

    ary | { |el| el + 5 }
Re:Streem – a new programming language from Matz by spoiler on Thursday December 11, 2014 @02:53PM (#8736719)
I prefer

    {|el| el + 5}
more than

    { _ + 5 }
the latter is too implicit for my taste, also I imagine it could become more confusing in a more complex context.
Re:Streem – a new programming language from Matz by rudolf0 on Thursday December 11, 2014 @03:01PM (#8736758)
Personally I like it and find it clear.

Compare:

    ary.map(_ * 2)

    ary.map(x => x * 2)
"_" is perhaps an ugly choice of character (frankly I'm not sure why Scala is so obsessed with it, since it's used for so many featurse), but I think the semantics are sensible.

Of course, in a more functional language you could perhaps just write

    ary.map(* 2)
Re:Streem – a new programming language from Matz by ssmoot on Thursday December 11, 2014 @03:59PM (#8737040)
> I'm not sure why Scala is so obsessed with it, since it's used for so many featurse

You might check out http://stackoverflow.com/a/8001065/3614122. The interesting thing (to me) is that the majority of those are actually the same feature (lifting functions). It's just such a powerful/flexible one that it's often misinterpreted as an entirely new thing in different contexts.

  ary.map(_ * 2)
Is no different than:

  val f = (_:Int) * 2

  ary.map(f)
Or:

  val f: Int => Int = _ * 2

  ary.map(f)
You're just using type-inference in conjunction with lifting. I wrote a blog post on it that's maybe not complete garbage. ;-) http://www.ssmoot.me/scala-s-magical-placeholder

Some of the other examples of the underscore are pattern-matches, which can be used on the LHS of assignment, similar to Erlang. Which comes in handy writing unit-tests. i.e.: If I expect something to return Some[User], and I'm writing a GET->UPDATE integration test, then I'd probably do something like:

  "Update should not blow up" in async {
    val Some(user) = await(db.get(userId))
    val update = user.copy(name = "bob")
    val Success(result) = await(db.put(update))
  }
Extractors/Pattern-Matching is way way up there for me. Much more significant than for-comprehensions. Though you could write the same code like:

  "Update should not blow up with a for-comprehension" in {
  
    val test = for {
      Some(user) <- db.get(userId)
      update = user.copy(name = "bob")
      Success(result) <- db.put(update)
    } yield result

    whenReady(result) { "whatever" }
  }
Re:Streem – a new programming language from Matz by saraid216 on Thursday December 11, 2014 @04:20PM (#8737122)
Your last example code is missing a closing-brace. I know no Scala, though, so I'm actually not sure where it should go.
Re:Streem – a new programming language from Matz by ssmoot on Thursday December 11, 2014 @04:50PM (#8737242)
Thanks. Missed it in the for-comprehension just before the yield.
Re:Streem – a new programming language from Matz by Alphasite_ on Thursday December 11, 2014 @03:51PM (#8737003)
What about a middle ground on swift's syntax?

    Arr.map { $1 * 2 }
Re:Streem – a new programming language from Matz by ryanlschneider on Thursday December 11, 2014 @05:30PM (#8737422)
That was going to be my suggestion too. With the added benefit that is supports multiple arguments.
Re:Streem – a new programming language from Matz by rudolf0 on Friday December 12, 2014 @03:48PM (#8742601)
Yeah, that'd be pretty cool.
Re:Streem – a new programming language from Matz by kbenson on Thursday December 11, 2014 @03:50PM (#8736999)
Probably because underscore is often used by convention in forms and other typography to indicate "something goes here which is to be supplied." In that respect it's no different that Perl's $_ (actually it's the Exact same thing, as the $ in Perl just denotes a variable, so they are both the variable _), or Perl 6's "whatever" which is written as "*".
Re:Streem – a new programming language from Matz by desdiv on Friday December 12, 2014 @12:11AM (#8738667)
Of course, in a more functional language you could perhaps just write "ary.map( * 2)"

Wait, isn't that already possible in Scala?

    ary.map(2*)
Re:Streem – a new programming language from Matz by breuleux on Thursday December 11, 2014 @03:52PM (#8737005)
This is not a confusing context, though. This would be a confusing context:

    ary.map(f(_ * 2))

    ==> ary.map(x => f(x * 2)) ?
    ==> ary.map(f(x => x * 2)) ?
How does Scala interpret that one? I have no idea.
Re:Streem – a new programming language from Matz by ssmoot on Thursday December 11, 2014 @04:11PM (#8737084)
It doesn't. It's invalid code in most (all?) cases.

  scala> val f: Int => Int = _ - 1
  f: Int => Int = <function1>

  scala> val ary = Array(1,2,3)
  ary: Array[Int] = Array(1, 2, 3)

  scala> ary.map(f(_ * 2))
  <console>:10: error: missing parameter type for expanded function ((x$1) => x$1.$times(2))
              ary.map(f(_ * 2))
                        ^
You can't think of "_" like a placeholder. It's not. It's to lift an argument of a function.

So simplify it: map in this context wants a Function[Int, Int] right? So f(_ * 2) must return a Function[Int,Int]. But it doesn't probably. _ is lifting some argument out of whatever f is. If you assume _ is an Int, does f take a Function[Int,Int]? No. It takes an Int. So there's no way to parse this that makes sense. It's not just "I have a stack of vars, pull one off the stack and bind it every time I write an underscore, reading left to right". That would be some AST generative grammar hack. That's not what the underscore is. It's simpler and more consistent than that.

What you're probably looking for instead is Function Composition. So something like:

  scala> ary.map(f compose(_ * 2))
  res10: Array[Int] = Array(1, 3, 5)
So why does that work? Because we were able to compose f() into a larger function that satisfies the signature of the argument map[T](Int => T) requires. A lot like a Stream conceptually.

(Is it correct to say in this context f() is a Monad? I'm not sure, I need to sit down and grok the category stuff sometime...)

Or you can write it the long way (calling f inside a new function). But instead of defining "steps" you'd be creating a new imperative function and driving the stack.

Re:Streem – a new programming language from Matz by breuleux on Thursday December 11, 2014 @06:32PM (#8737675)
That's interesting, but you did not answer my question. I wanted to know how Scala determines where to insert =>. In my example, Scala interprets "ary.map(f(_ * 2))" as "ary.map(f(x => x * 2))" (both of these expressions yield the same error). If it interpreted it the other way, then the expression would work (using your definition of f). Perhaps a better example to use would have been:

    Array((_:Int) * 2)

    ==> (x:Int) => Array(x * 2) ? (correctly typed)
    ==> Array((x:Int) => x * 2) ? (also correctly typed)
As it turns out, Scala goes for the latter. After playing with the feature a bit I'd say the rules are engineered to fit particular use cases, but they can be a bit finicky if you venture outside of them. For instance, "1 + _ * 2" will work, but "(1 + _) * 2" won't. "f(_)(x)" does not mean the same thing as "(f(_))(x)".

I mean, I wouldn't say the feature is bad, but it definitely has a DWIM vibe to it that would make me classify it as a hack.

Re:Streem – a new programming language from Matz by ssmoot on Thursday December 11, 2014 @08:36PM (#8738157)
> In my example, Scala interprets "ary.map(f(_ * 2))" as "ary.map(f(x => x * 2))"

I think this is where I'm not communicating what I'm trying to say very well. What I'm trying to say is that that statement is false.

The underscore isn't a placeholder saying "inject a Function here". You probably didn't mean that exactly of course, but it's a programming language; it pays to be a bit pedantic I think.

It's easier to understand if you work backwards maybe.

Is this valid?

  (_:Int) * 2
Of course. It's a Function[Int,Int]. The important part is the asterisk method that's being lifted to a Function.

So now you take that perfectly valid piece of code lifting a method to a function and you pass it to Array.apply:

  Array.apply((_:Int) * 2)
Why should your code start behaving differently? That wouldn't be consistent at all. You had a Function[Int,Int] before, but now that you've passed that function value to Array.apply instead of getting an Array[Function[Int,Int]] as you would in every single other case, you get a Function[Int,Array[Int]]?

What sense does that make? That seems like straight up voodoo.

There's some syntax supporting this feature. But not so much as you think. It's just the "lift". Type-inferencing lets you get away with what looks like a little more sometimes.

I dunno. Maybe that's helpful. Maybe not.

Re:Streem – a new programming language from Matz by breuleux on Thursday December 11, 2014 @09:32PM (#8738339)
> The underscore isn't a placeholder saying "inject a Function here".

It is. Look at the error message:

    error: missing parameter type for expanded function ((x$1) => x$1.$times(2))
It did inject a function, it's right there, in plain text. Then it did type inference. I mean, what else is "lifting" the asterisk to a Function supposed to mean, if not injecting a function around a placeholder? And what about "1 + _ * 2"? What is it lifting? The asterisk? No. It is lifting more than that.

> You had a Function[Int,Int] before, but now that you've passed that function value to Array.apply instead of getting an Array[Function[Int,Int]] as you would in every single other case, you get a Function[Int,Array[Int]]?

That's besides the point. The question is, when the parser sees "_", how much of the context does it grab along with it? In other words, I know it's lifting stuff, what I want to know is how much it lifts. Here's another example:

    f(_, 2)(3)

    ==> x => (f(x, 2)(3)) ?
    ==> (x => f(x, 2))(3) ?
Scala does the former. That's a legitimate choice given common use cases, but the latter is simpler, preserves the invariant that "a(b) <=> (a)(b)" and has use cases as well, e.g. to make an expression like "f(super_long_expression, 2)" more readable.

> But not so much as you think. It's just the "lift". Type-inferencing lets you get away with what looks like a little more sometimes.

I still don't see what type inference has to do with this. The error message makes it clear that the lift is done before type inference kicks in. In a dynamic language, you would stop at the lift, but it would otherwise work just the same.

Re:Streem – a new programming language from Matz by ssmoot on Friday December 12, 2014 @10:38AM (#8740593)
> It did inject a function, it's right there, in plain text. Then it did type inference.

Yes, the inferencer/type-resolver runs after the parser (there's a recent thread on the ML about a Parboiled parser you might find interesting BTW). My point was this is parsed. It's an AST at that point, it just hasn't resolved the types yet. It's not a source preprocessor. To me that implies limitations, but also an expectation of consistency.

> ... what about "1 + _ * 2"? What is it lifting? The asterisk? No. It is lifting more than that.

Yes! Paste your code into the REPL and see what you get:

  scala> 1 + _ * 2
  <console>:8: error: missing parameter type for expanded function ((x$1) => 1.$plus(x$1.$times(2)))
              1 + _ * 2
This is a real hairy example IMO since it's conflating the mechanics with optional parenthesis and dot-less method calls, but we can break it down just the same. Since Int.+ takes a single argument, then it must parse as:

  1.+(_ * 2)
NOT

  (1 + _) * 2
The first example is trying to lift $times from something. The second is trying to lift the instance-method that's already bound to 1:Int to a Function0[Int].

They're doing exactly the opposite thing right? It's like assuming that the LHS and RHS of an assignment are interchangeable. They're not. One is a label and one is a value.

> how much of the context does it grab along with it?

None. In this position, it's the beginning of an expression. It doesn't escape the scope it's defined in. Just like in the 1.+(_ * 2) example, what comes before it doesn't matter. It's the beginning of an expression.

> I still don't see what type inference has to do with this.

I probably just complicated things bringing it up. ary.map(_ * 2) vs ary.map((_:Int) * 2). I feel like maybe it's not understood that those do the same thing. The only difference is the type is inferred from the signature of map[T] (simplified minus CBF) on the first.

I'm not trying to debate that sometimes it's frustrating that I can't just:

  documents foreach(couchdbActor ! Queue(json.merge(_)))
Intuitively, it seems like it's possible it could work. And it might if the underscore was accomplished through code-rewriting of some sort right? But it's not. So what I'm doing is:

  documents foreach(couchdbActor.tell(Queue(JsObject => JsObject))
I'm not satisfying the signature of foreach because tell() isn't returning a Function[JsObject,Nothing], and I'm passing a Function[JsObject,JsObject] to Queue.apply (case class Queue(payload:JsObject)). Neither of those things makes sense. So what I do instead:

  documents foreach((couchdbActor ! _) compose Queue compose json.merge)
Breaking that down, I've got:

  (couchdbActor ! _) // This just lifts the tell method, which gives me a Function[Any,Unit].

  Queue.apply // Function[JsObject,Queue]: I can compose that with my lifted tell to get a Function[JsObject,Unit]

  json.merge // Function[JsObject,JsObject]: Doesn't change the signature: Function[JsObject,Unit]
Now foreach() gets passed a Function[JsObject,Unit]. Which is exactly what it's expecting.

When you break it down, you have to keep a "stack" in your head. Which can get hard sometimes (at least for me), but the underlying consistency about what's actually happening makes it simple to do. It's like a basic addition problem:

  27 + 34 + 192 + 11
I expect for most people that takes some deliberate thought, breaking it into smaller operations, carrying the result in your head as you go. But it's still simple, because it's consistent.

> In a dynamic language, you would stop at the lift, but it would otherwise work just the same.

I was going to attempt to write a Ruby analogue, but I can't actually figure out a clean way to do that.

I dunno. I feel like you probably understand all this just fine. You just don't like it. You'd prefer a sort of source-rewriting approach? So maybe Scala just isn't the language for you. I feel like once you understand the mechanics of the underscore, it's pretty straight-forward. Similar to beginners getting tripped up on for-comprehensions:

  val o = Option(1)
  val f = Future.successful(List(2,3,4))

  for {
    n <- o
    l <- f
    x <- l
  } yield n + x
That trips up everybody at some point right? If you understand that it's just map, flatten and filter, it's clear why that doesn't work though. How do you say: Option(Future(2)).flatten? What would that do? Can't work. It may be initially frustrating for new users, but it's consistent. If you study the mechanics, then it becomes second nature. The mystery disappears. That's really all I was trying to do here. Hopefully someone finds it useful.

Side note: This is a big part of why I find for-comprehensions mostly useless. They do nothing you can't already do, and they introduce what can look like magic. They're pure sugar, except more often than not, they're also longer to write. Plus they're mostly useless outside of testing. How often do you want a Failure to just throw? Or a Play Action to return a None? More often than not, you're gonna want to fold(), getOrElse(), match { case None => NotFound; case Some(foo) => ... Ok(finalResult) } etc. But I digress. :-)

Re:Streem – a new programming language from Matz by breuleux on Friday December 12, 2014 @02:56PM (#8742338)
> This is a real hairy example IMO since it's conflating the mechanics with optional parenthesis and dot-less method calls, but we can break it down just the same. Since Int.+ takes a single argument, then it must parse as:

> 1.+(_ * 2)

No, my point is that this is not how it parses. Look:

    ary.map(1 + (_:Int) * 2)
    res3: Array[Int] = Array(3, 5, 7, 9, 11)
    ary.map(1.+((_:Int) * 2))
    error: overloaded method value + with alternatives:
      (Double)Double
      ...
In the first case, the parser lifts _ over $times AND over $plus. The function is being lifted over both of them. The optional parentheses break the feature if you insert them: "1.+(_ * 2)" tries to add one to a function, which is not a valid operation.

>> how much of the context does it grab along with it?

> None. In this position, it's the beginning of an expression. It doesn't escape the scope it's defined in. Just like in the 1.+(_ * 2) example, what comes before it doesn't matter. It's the beginning of an expression.

If that was true, then "1 + _ * 2" would be invalid, and "f(_)(1)" would be equivalent to "f(1)". But the former is valid and the latter doesn't work like that.

> I was going to attempt to write a Ruby analogue, but I can't actually figure out a clean way to do that.

There is a limited Python analogue:

https://github.com/kachayev/fn.py#scala-style-lambdas-defini...

That only works insofar that the _ placeholder object can seize control over the expression, so "f(_, 2)" won't work unless f explicitly handles _. Implementing the full feature would require language or macro support, but my point was more that a new dynamic language could trivially support it.

Re:Streem – a new programming language from Matz by msie on Thursday December 11, 2014 @11:29PM (#8738565)
For only several characters more the second form is much clearer to many more programmers. I think it's worth it.
Re:Streem – a new programming language from Matz by breuleux on Thursday December 11, 2014 @03:34PM (#8736918)
Personally I would go for something more like this:

    STDIN | /\w+/ | {|each match|
      /house/   => "foo"
      /car/     => "bar"
      "literal" => "baz"
      _         => "dib"
    }
Where "each x" in a parameter list wraps the body in a map and uses x as the loop variable, and "match" in a parameter list instructs that this is the parameter we are doing pattern matching on in the body (no need to name it).

I think this is a more flexible solution, and more modifiers than each could be introduced. For instance, sum of squares could be:

    seq(100) | {|each x| x * x} | {|reduce (x = 0, y)| x + y}
Re:Streem – a new programming language from Matz by bjourne on Thursday December 11, 2014 @08:53PM (#8738205)
This is how you would write it in factor:

    "~/yourfile.txt" utf8 file-contents 
    "\\w+" findall [ first second ] map [ 
        { 
            { "house" [ "house stuff" print ] } 
            { "car" [ "car" print ] } 
            [ "default stuff: %u\n" printf ] 
        } case 
    ] each
Tacit programming basically is the same thing as stream programming.
Re:Streem – a new programming language from Matz by ori_b on Thursday December 11, 2014 @01:39PM (#8736367)
Sounds like a job for structural regex: http://doc.cat-v.org/bell_labs/structural_regexps/se.pdf
Re:Streem – a new programming language from Matz by dwenzek on Friday December 12, 2014 @04:31AM (#8739224)
Yes, this paper is interesting.

It shows well how a slight shift on the problem expression can lead to a more powerful, simpler to use and general solution. In this case, the shift is to design stream processors (like `sed` and `awk`) to work on streams of text chunks defined by regular expressions rather on streams of lines matching regular expressions.

Regarding this concern, it's hard to say what is the plan of Matz for Streem with a single code example. But the fact, that this sample code processes a stream of integers, lets hope a tool with more flexibility than `sed` or `awk` to specify what is processed along the streams.

Re:Streem – a new programming language from Matz by klibertp on Thursday December 11, 2014 @07:50PM (#8737994)
Take a look at TXR: http://www.nongnu.org/txr/

The link was posted on HN some time ago and was generally well received. I didn't have the time to use it much yet, but it looks very nice. Well, unless you hate lisp.

Re:Streem – a new programming language from Matz by bglazer on Thursday December 11, 2014 @05:42PM (#8737471)
I'd like to recommend a python command line utility called pyp. It allows you to do python string manipulation on text streams using the standard pipe operator.

https://code.google.com/p/pyp/

Re:Streem – a new programming language from Matz by vram22 on Thursday December 11, 2014 @05:52PM (#8737512)
Yes, pyp is interesting. So are some other roughly similar Python tools for doing pipe-like stuff. I had blogged about some of them here, a while ago, including pyp, osh, and pipe (not the Unix pipe system call, but a Python module):

Some ways of doing UNIX-style pipes in Python:

http://jugad2.blogspot.in/2011/09/some-ways-of-doing-unix-st...

And that later inspired me to create an experimental tool called pipe_controller:

Swapping pipe components at runtime with pipe_controller:

http://jugad2.blogspot.in/2012/10/swapping-pipe-components-a...

The above post links (recursively) to a few others, also by me, describing a couple of other ways of using pipe_controller, including this one:

Using PipeController to run a pipe incrementally:

http://jugad2.blogspot.in/2012/09/using-pipecontroller-to-ru...

and also includes the link for it on my Bitbucket account.

There's also plumbum, another such Python module.

Re:Streem – a new programming language from Matz by jkgeyti on Friday December 12, 2014 @05:26AM (#8739372)
I found it cumbersome to do branching in most of the existing python stream tools. I made an alternative, that allows you to use curly brackets for indentation:

https://github.com/ircflagship2/pype

Re:Streem – a new programming language from Matz by pablovidal85 on Thursday December 11, 2014 @07:49PM (#8737990)
This inspired me to build a similar tool which runs javascript instead.

https://github.com/aynik/sx

Re:Streem – a new programming language from Matz by mamcx on Thursday December 11, 2014 @02:53PM (#8736720)
" new stream processing language"... which are the olds?

I'm playing with the idea of build a language, where the functions are unix-like, with STDIN, OUT & ERR. So, instead of raise a exception, it put data in ERR... and make it easy to compose them.

Re:Streem – a new programming language from Matz by c3RlcGhlbnI_ on Thursday December 11, 2014 @03:33PM (#8736911)
There don't seem to be that many that work on text streams, which is what I was referring to. The ones I am aware of are awk, shell scripting languages(bash, zsh, ksh, etc.), and the ed like DSLs( sed, ed, sam, etc.). I think there are others that are not as widely used.

If you google stream processing language you will also get a whole bunch that are not text specific. They are definitely worth looking at if you are interested in building any kind of stream based language.

Re:Streem – a new programming language from Matz by marianov on Thursday December 11, 2014 @08:54PM (#8738209)