The long arrow operator in C++ - <AUTHOR> http://cukic.co/2017/07/12/the-long-arrow-operator-in-cxx/ <comment><USER2> Obligatory "x slides to zero":

      while (x --\
                  \
                   \
                    \
                     > 0)
           printf("%d ", x);

<comment><USER3> Also, never forget, the C++ Multi-Dimensional Analog Literals:

      assert( ( o</comment></comment><comment></comment><comment>-o
                |L             \
                | L             \
                |  L             \
                |   o</comment><comment></comment><comment>-o
                |   !             !
                !   !             !
                o   |             !
                 L  |             !
                  L |             !
                   L|             !
                    o</comment><comment></comment><comment>-o ).volume == ( o</comment><comment></comment><comment>-o
                                                  |             !
                                                  !             !
                                                  !             !
                                                  o</comment><comment></comment><comment>-o ).area * int(I</comment><comment></comment><comment>-I) );

[http://www.eelis.net/C++/analogliterals.xhtml](http://www.eelis.net/C++/analogliterals.xhtml)

<comment><USER4> This is some serious black magic. I cannot wrap my head around the fact that this is valid C++...

<comment><USER5> These are "just" some free symbols (o, I, L) used with overloaded operators (!, |, --). The rest is pretty formatting with whitespace which isn't relevant to functionality.

</comment></comment></comment><comment><USER6> I remember this from a similar example in C:

       #include <stdio.h>
       int main()
       {
           int x = 10;
           while (x --> 0) /* x goes to 0 */
           {
              printf("%d ", x);
           }
       }

(prints 9 8 7 6 5 4 3 2 1 0)

[https://stackoverflow.com/questions/1642028/what-is-the- oper...](https://stackoverflow.com/questions/1642028/what-is-the-operator- in-c)

<comment><USER7> Works just as well in Java. I'll have to slip this in to my next code review :)

<comment><USER8> Careful with these jokes -- your coding style nazis will give you a new coding rule in return to prevent this madness in the future!

<comment><USER9> Or, worse, adopt it as the way to do things.

I blame Haskell, Scala, and Ruby.

<comment><USER6> > Or, worse, adopt it as the way to do things.

Thompson, Ritchie and Kernighan admit that Unix was a prank

[http://www.stokely.com/lighter.side/unix.prank.html](http://www.stokely.com/lighter.side/unix.prank.html)

</comment></comment></comment></comment></comment><comment><USER10> You can even approach 0 from left and right simultaneously:

        while (a -->> k --> 0 <-- b <<-- c)

and you can have dashed arrows too:

        k = a <- - - - - b;

<comment><USER11> In the dashed case, k is going to be zero or one (a<b is true or false). This works, though:

            int a=0, b=4;

            while(a < - - - - --b) {
                    printf("b: %d\n", b);
            }

<comment><USER10> I just spent an hour constructing a class called Morse such that this outputs "HELLO WORLD!":

        Morse m;
        cout << (++++m) << (+m) << (+-++m) << (+-++m) << (---m) << ", "
             << (+--m) << (---m) << (+-+m) << (+-++m) << (-++m) << "!\n";

Damn you, C++! Why won't you let me overload the . operator? ;-)

</comment></comment></comment><comment><USER12> In python there is the term "pythonic" describing if something is in the spirit of the languages founding fathers. As in: "The most pythonic way to write this down is ..." or "Map/filter don't feel very pythonic."

What is the equivalent term or expression for being in the spirit of C++?

The article, while a joke (just like C++ originally, look it up), feels very C++y.

<comment><USER13> I think the word is "confusing"

<comment><USER14> I was once taught, "In C, calling a solution 'interesting' is a compliment. In Python, that's an insult. Maybe we should go with "interesting".

</comment></comment></comment><comment><USER15> Cute. Though if I actually saw this in a codebase I might tear my hair out.

</comment><comment><USER16> Even if it's a Joke, C++ lost me a decade ago...

<comment><USER17> That's a shame. C++11/14/17 each make the language better and deal with many of the might have pushed someone away in the past.

The typing is getting stronger, the library richer and hard things easier. If you know about or can google RAII and are willing to lookup things on occasion to pick algorithms or just the right member function, code gets very clean. After not too long the looking stops because the std lib is still pretty small compared to other languages.

But if you have already moved to Rust I can't make an objective argument for it.

<comment><USER18> > C++11/14/17 each make the language better and deal

That may be true, but all you are seeing is C++ copying from every other language in an effort to once again become relevant.

IMHO in this modern day and age there are so many easier, better, more expressive, easier to use languages than C++ to choose from.

And that is coming from someone who spent a lot of time coding C++ some 15 years ago.

<comment><USER17> > an effort to once again become relevant.

I was unaware that being the 2nd and 3rd most popular language made it not relevant when I guess nothing is relevant except Java. (Per the Tiobe index)

If you need high level abstractions and the ability to tweak for performance at the lowest levels the it is either C++ or Rust, and if you need a mature ecosystem that really only leaves C++. Game devs, Google, Facebook, HPC and tons of stuff and now with emscripten and WASM we get to compete with JS devs for in browser games too!

</comment></comment></comment></comment><comment> awinter-py and don't forget the equally useful and serious integer unary-double-equal greater-than operator

      8==>

<comment><USER19> I guess if this was Reddit, we would have had a meme storm by now...

</comment></comment><comment><USER20> Law of Demeter, much?

</comment><comment><USER18> Is this an Aprils fools joke posted a few months late?

</comment><comment><USER21> Why??????????????????????????

<comment><USER12> It's a joke.

<comment><USER22> They had me because it was so similar to the - very real - combinations of "conses" in the lisp world: caaaar, cdaddr, cddddr and so on. [https://franz.com/support/documentation/6.0/ansicl/dictentr/...](https://franz.com/support/documentation/6.0/ansicl/dictentr/carcdrca.htm)</comment></comment></comment>


Uber stripped of licence to operate in London - <AUTHOR> https://www.ft.com/content/78827b06-0f6a-11ea-a225-db2f231cfeae <comment><USER2> Also at: [https://www.bbc.co.uk/news/business-50544283](https://www.bbc.co.uk/news/business-50544283)</comment>


America's Coal Consumption Entered Free Fall in 2019 - <AUTHOR> https://www.theatlantic.com/science/archive/2020/01/americas-coal-consumption-entered-free-fall-2019/604543/ <comment><USER2> What does 'plodding' mean in this context?

> "... Last year, American greenhouse-gas pollution fell by 2.1 percent, > driven almost entirely by coal's decline and a plodding economy..."</comment>


Everyone Who Believes In Bitcoin Should Try To Answer This Question - <AUTHOR> http://www.businessinsider.com/everyone-who-believes-in-bitcoin-should-try-to-answer-this-question-2013-12

<comment><USER2> Good questions, but I think the answer for gold is pretty weak as well:

 _> Underpinning the value of gold is that if all else fails you can use it to make pretty things._

That's true, but where would the price of gold be if there was only jewelry demand left in the market? I think gold as a store of value depends on psychology, not on jewelry. But it is a kind of psychology that is impossible to replicate for anything newly invented.

</comment><comment><USER3> This was discussed at length in the "Bitcoin is Evil" thread yesterday, but the general idea is that Bitcoin can still be used to make "pretty things" even if you aren't using it as a medium of exchange. Namecoin is one particularly interesting example - fully decentralized DNS. The ability to conduct authenticated P2P transactions of _any_ nature, not just financial, is what makes Bitcoin and its ilk interesting, IMO.

<comment><USER4> nonono. namecoin is not bitcoin. you are explaining why proof-of-work-schemes are useful. that is not the question.

the article (quoting Krugman) says that there are good reasons why bitcoin might be a wonderful medium of exchange, but there is no good reason why it is a good store of value.

<comment><USER5> That specific premise is false. An alternate use case does not provide a -meaningful- floor for any store of value. Tulips still have an alternate use case.

I'd claim Krugman is arguing against cryptocurrency in general rather than Bitcoin specifically.

The affordances provided cryptocurrency are new. It's a fair bet that will provide value.

How many factors currently contributing to the value of the US dollar were in place within the first decade of its existence?

I'd also claim the libertarian hopes for cryptocurrency are overblown, though they are definitely contributing to its current level interest.

</comment></comment></comment><comment><USER6> IIRC, Paper money used in the colonies had the exact same problem as Bitcoin, but many different forms of them worked prior to the establishment of the United States and the US Mint. Not everything pre-United States was traded in gold, furs and wigwam. They were a fiat currency that could not be used to pay taxes.

What Krugman fails to consider time and time again is the notion of "fitness for use". For international transfers, bitcoin has greater fitness for use than any international currency or other medium of exchange out there. What's missing is fitness for use for day to day transactions, usability, security for the average person and volatility. The former three are being worked on by many people and being solved little by little, and those three are contributing to reduce volatility relative to it's moving average price relative to other currencies.

</comment><comment><USER7> Just its existing network effect.

A new blockchain, alt-coin, or ripple-type system can and do pop up all the time, but bitcoin has a significant network.

If someone invested in building out a new digital payment network they could overtake bitcoin. But its not getting easier every day as bitcoin adoption grows.

</comment><comment><USER8> I am the answer. I place a floor on the value of bitcoin. So do all other believers. To be clear, for all those out there confused, bitcoin is not just money, it is not just a way to make money, it is a movement to change the meaning of money. Only upon grasping that will the perplexed begin to understand.

<comment><USER9> Faith is fickle.

The problem with your statement is that there may be a new digital currency that displaces Bitcoin ... namecoin, anycoin, litecoin, dogecoin. Maybe not one of those, but a 2.0 of some sort that attracts the miners.

If a NEW Bitcoin equivalent takes the spotlight and Bitcoin miners retrofit their rigs to mine for the new network, then someone that had put all of their money into Bitcoin could lose it all.

Nothing guarantees the continued use of Bitcoin. It is a decentralized fiat currency.

<comment><USER6> Nothing guarantees that a new currency will displace Bitcoin rather than complement it. A second or third or fourth crypto-currency with broad adoption like Bitcoin would help Bitcoin more than hurt it since they would suggest that crypto-currencies are here to stay forever.

It's entirely conceivable that in the future there are half a dozen or more crypto-currencies out there that provide different qualities that make them more or less fit for use by different groups of people.

</comment></comment></comment><comment><USER4> _Placing a floor on the value of bitcoins is… what, exactly?_

Nothing but the trust of those involved. Plain and simple.

<comment><USER6> And the investment already poured into it. A lot of people now have a vested financial interest in making it succeed. There are enough of those people to make it self-sustaining while the kinks are worked out.</comment></comment>


Just do the Demo - <AUTHOR> http://ricksegal.typepad.com/pmv/2009/05/just-do-the-demo.html <comment><USER2> _"It's a compliment when you are asked to skip the slides and just do the demo. Really."_

Back in 1999 I was at the bottom of the hierarchy of a 2000-person company, presenting to the CFO. After two slides she said, "OK, what's your recommended solution?"

I said, "I haven't finished laying out the problem!"

She said, "That's fine, what are your recommendations?"

I was young and stupid and insisted on showing her how significant the problem was before going on to the recommendations section. I had thought out the problem so well, and I felt upper management _had_ to understand the arguments I was making.

In retrospect, I can imagine that she had some trust in the tech people working there, and _believed_ when she was told there was a problem. But I had run into so many mid-level people who didn't understand that there even _was_ a problem, that I felt I had to sell the CFO something she was already sold on.

I think this is part of that mystical quality, 'experience': realizing when the reality of someone you're talking to is different from the realities of the last 99 people you talked to, and adjusting the message accordingly.

I can imagine that, in terms of evaluating pitches, VCs and angels inhabit very different realities than one's friends & colleagues.

</comment><comment><USER3> In part this comes down to some advice I was given many, many years ago:

 _Learn to listen._

It's not just to listen to the exact words, but also to the message behind them. Learn to find the message, and if you're not sure what the message is, ask questions to elucidate.

In the case given the message is something like _"I see your point, I trust you, move along, I don't need convincing."_

If you think the do still need convincing, ask. They're being blunt with you, you be straight with them.

For neuro-typicals this is fairly easy. For most tech people it's a skill waiting to be learned.

Learn it - it's valuable. Trust me, and move on.

<comment><USER4> Very, very good advice.

To make a parallel, quoting Issac Asimov "The most exciting phrase to hear in science, the one that heralds new discoveries, is not 'Eureka!' (I found it!) but 'That's funny ...'". Meaning that you need to pay attention to the small messages, and you do that by listening.

</comment></comment><comment><USER5>
      After making Michael Arrington "no hand shake" jokes...

Apparently MA is from Techcrunch. I can't find a reference to his hand shake jokes though.

Does anyone would like to fill me in?

<comment><USER6> [http://www.techcrunch.com/2009/05/09/hand-shaking-is-so- medi...](http://www.techcrunch.com/2009/05/09/hand-shaking-is-so-medieval- lets-end-it/)</comment></comment>


Ask HN: Free resources for a dev to learn sales? - <AUTHOR> Want to expand the skillset and as a dev the skill I'm lacking the most is sales. <comment><USER2> There's been a topic recently on HN where an engineer was going into selling tech services. A lot of good advice there, including mine.

<comment><USER2> Here you go: [https://news.ycombinator.com/item?id=23475085](https://news.ycombinator.com/item?id=23475085)

</comment></comment><comment><USER3> From personal experiences, take a work such as stock broker really increases sales skill.</comment>


TamaGo – Bare Metal Go for ARM SoCs - <AUTHOR> https://github.com/inversepath/tamago <comment><AUTHOR> Learned about this in a talk at 36C3 and it looked pretty cool [1]. The recording should be up soon at [2].

[1]: [https://fahrplan.events.ccc.de/congress/2019/Fahrplan/events...](https://fahrplan.events.ccc.de/congress/2019/Fahrplan/events/10597.html) [2]: [https://media.ccc.de/recent](https://media.ccc.de/recent)

</comment><comment><USER2> Related... enables you to build your own Trezor/Ledger secure wallet... [https://www.f-secure.com/en/consulting/foundry/usb- armory](https://www.f-secure.com/en/consulting/foundry/usb-armory)</comment>


Ask HN: implementing realtime on iPhone - <AUTHOR>

I'm finding a dearth of clients that talk some sort of push protocol for iOS. I've been implementing my bits with in app routing for APNs but am looking for something more... real (Can't be spamming push notifications when users are out of app, right?)
So far I've only found an iPhone STOMP client here https://github.com/juretta/objc-stomp that I could hook up to something like Orbited, and I would like to get all my options on the table if anyone could help me out.
There's always the option to pick damn near any  evented server and fill in the dots client side with something like http://code.google.com/p/cocoaasyncsocket/ , but more un-wheel-reinventing suggestions would be  preferable! Thanks <comment><USER2> I've had great luck with using xmpp with pubsub as a method of client/server communication. It has a number of advantages in that once you've converted your commands to xml in an xmpp payload you can route to a variety of backend services that speak xmpp. You also get things like presence for free which can be useful in many cases. This might be useful: <http://code.google.com/p/xmppframework/wiki/iPhone> Here's an excellent scalable xmpp server that's highly extensible: <http://ejabberd.im></comment>


A Democrat is running for president on a platform of Universal Basic Income - <AUTHOR> https://mobile.nytimes.com/2018/02/10/technology/his-2020-campaign-message-the-robots-are-coming.html <comment><USER2> How is he proposing to pay for UBI aged 18-64? The only way I would support a UBI is to completely eliminate social programs like welfare, food stamps, and housing assistance. It may then be cost-neutral.

Also, this language is just not accurate:

> unraveling President Trump's tax breaks for the wealthy

It is mostly for corporations; middle-class citizens will also see a reduction in their taxes. Until the market meltdown last week, the new tax plan was widely praised even by very liberal business leaders such as Tim Cook. US corporate taxes were absurdly high and tax reform has been positive in terms of the slew of bonuses offered to employees (not executives), raising of corporate profits, and helping repatriate huge amounts of capital back to the US.

<comment><USER3> The tax breaks for the middle class are only temporary. Most CEO's are praising them because it's great for them and shareholders. Most CEO's acknowledge they will use the additional profits to perform share buy backs.

While the middle class got something, the majority went to the wealthy, and as per my previous comment on shares, they are not going to be flooding it back into the economy.

Also US corporate taxes were about median for the world, they were not absurdly high, you should check out some countries in Europe for that.

<comment><USER2> See this NPR[1] article which listed the previous US corporate tax rate as the highest of advanced economies. This included France, Belgium, Germany. Also fun fact, go visit Dublin and see all the tech companies (Google, Facebook, Microsoft, etc) who have a Europe HQ there. The reason, they have a 12.5% corporate tax rate.

[1] [https://www.npr.org/2017/08/07/541797699/fact-check-does- the...](https://www.npr.org/2017/08/07/541797699/fact-check-does-the-u-s-have- the-highest-corporate-tax-rate-in-the-world)

<comment><USER4> The effective US corporate tax rate is more median. Our headline tax rates were higher, but we also had larger deductions and tax credits.

<comment><USER5> That is a very bad policy to have though because it encourages wasteful spending on tax avoidance and rewards the companies that do it. It also gives an artificial competitive advantage to the largest companies, who have the scale to invest in complex tax avoidance schemes, at the expense of smaller more productive companies.

</comment></comment></comment></comment></comment><comment><AUTHOR> Interesting notes from article:

\- Political platform centered around automation impact on labor market.

\- Proposing a UBI paid for by a higher corporate tax rate targeted at companies benefiting most from automation.

\- Would be $1,000/mo paid to everyone aged 18-64, with no means test.

\- Candidate is the former CEO and founder of Venture for America, Andrew Yang. He is 43 and already has backing of many Dem-leaning tech executives.

</comment><comment><USER6> I think a better solution would be a negative tax rate instead of a 0% tax rate.

Imagine: On your first $24,000 / Year, you are taxed at -50%. This means, if you make $12,000, you get paid an additional $6,000. If you make $24,000, you get paid an additional $12,000. This is an additional reward for working! We want to incentivize working!

<comment><USER7> how's that fair if you have person a working in a callcenter for slightly better pay than person b working at McDonalds.

Person A makes 20k, person B makes 10k. Both work pretty shitty jobs -- I wouldn't want either.. Both work the same hours. No more jobs exist for Person A's job, so Person B couldn't rise up to their level if they wanted to.

GBI works because everybody gets it -- so nobody feels like they're getting special treatment, nobody feels like they're on welfare (which causes a mental stigma to begin with) and the goal is simply to cover average rents and maybe some food. Everyone should have food and a roof.

Your plan also doesn't account for what happens when all the jobs for both A and B close down because of automation which is the whole point for why we're discussing GBI more and more anyways.

<comment><USER8> I'm pretty sure the person you replied to was being satirical.

<comment><USER9> I'm not sure why: a NIT has some advantages relative to UBI.

</comment></comment></comment></comment><comment><USER10> I see this as another welfare program and we already have too many welfare programs.

If we all see that automation is or will be a problem for the labor market, isn't it makes more sense to get the labor market ready to embrace the automation era?

Instead of making our youth going through college, why not have them sent to learn a craft or skill set?

I personal think only those who are good with school and like school should go to higher education. For the rest of us, a 4 years experience with no debt is far better 4 years education with 50 to 100k in student loan debt

<comment><USER11> What are these jobs that you think will resist robotic automation, and how many of them will there be? Realistically a small percentage of people will ever be programmers in our society; we just don't need that many.

Look, we're entering a period of history where the number of tasks requiring human labor _will only keep decreasing_. This will lead to a growing class of people for whom the labor market cannot provide a basic standard of living.

If a stronger welfare state isn't the answer to that problem, I've yet to hear what _is_ , exactly.

<comment><USER12> > "What are these jobs that you think will resist robotic automation, and how > many of them will there be?"

Trades like plumbing, electrician, lineman, P&C technician, mechanic, power plant operator, transmission/distribution operator, welder, etc...

<comment><USER11> How many more plumbers and electricians do you think we need? I see no reason to think that the supply of those trade jobs in the labor market would increase to match the demand caused by automation layoffs. (Also, what makes those jobs impervious to automation?)

</comment></comment></comment></comment><comment><USER13> I heard an interesting comparison last week.

This author noted that the farm equipment revolution threw a very high percentage of Americans out of work. They were forced off the farm and had to move to the cities (where the industrial age was hitting it's stride.)

It wasn't easy, but it led to huge improvements in quality of life.

</comment><comment><USER9> Is there somewhere I can make a bet on whether 94% of the truck drivers will be out of work in a few years?

I'm really skeptical.

</comment><comment><USER14> Partial communism? There is a time for that but until more jobs are taken over by automation or robots, this would just slow down a lot of progress

<comment><USER15> _More_ jobs? For the last 200 years, machines have taken over entire industries of jobs.

People to cut the crops, people to harvest lax, people to spin wool, people to weave cloth, people to make soap, street cleaners, navvies, telephone operators, travel agents, and the list goes on.

Sure, there are still people who do all of those, but not like it used to be.

And this transition, that is, the use of automation to increase the power of capital by decreasing the cost of labor, is what lead to the original ideas of full communism.

</comment></comment><comment><USER16> Back in the early 80s when Reagan was decrying welfare and it's costs vs. benefits he joked that it would be cheaper for the U.S. government to abandon the relevant federal agencies and just send recipients a check each month. Full circle I suppose.

<comment><USER7> Wow, something I actually finally agree w/ Reagan on -- mostly because I'm anti-bureaucracy. Mailing checks can be automated and allow for closing all welfare offices and firing all the staff that run those agencies, cutting the utilities, selling the land, etc...

I'm also for single-payer because we spend too much on Sales/Commercials/CEOS for insurance companies, and medical billers who we could all put out of jobs because all they do is figure out how to pay hospitals and collect money from us or our employers.

I feel though that trickle-down has failed immensely. The fact is trickle-out is what happened trickle-out-to-my-caymen-island-account.

Rich just re-invest/hoard money. Now if they'd trickled up... it would've worked wonders for the economy. Give the poorest of the poor money --and they'll spend it on booze/drugs/homes/food does it matter? The money still circulates and finds it way back up to the rich/b2c businesses.

$10k given to Bill Gates goes into the bank account, and stays their collecting dust and interest. $10k given to a struggling family goes into a new car, or braces for Jimmy, etc... Which in turn goes to payroll for employees at the dentist or car-lot, and that goes on and on...</comment></comment>


Show HN: Riko – A Python stream processing engine modeled after Yahoo! Pipes - <AUTHOR> https://github.com/nerevu/riko <comment><AUTHOR> `riko` is pure python stream processing library for analyzing and processing streams of structured data. It's modeled after Yahoo! Pipes [1] and was originally a fork of pipe2py [2]. It has both synchronous and asynchronous (via twisted) APIs, and supports parallel execution (via multiprocessing).

Out of the box, `riko` can read csv/xml/json/html files; create text and data based flows via modular pipes; parse and extract RSS/ATOM feeds; and bunch of other neat things. You can think of `riko` as a poor man's Spark/Storm... stream processing made easy!

Feedback welcome so let me know what you think!

Resources: FAQ [3], cookbook [4], and ipython notebook [5]

Quickie Demo:

        >>> from riko.modules import fetch
        >>>
        >>> stream = fetch.pipe(conf={'url': 'https://news.ycombinator.com/rss'})
        >>> item = next(stream)
        >>> item['title'], item['link']
        ('Master Plan, Part Deux', 'https://www.tesla.com/blog/master-plan-part-deux')

[1] [https://web.archive.org/web/20150930021241/http://pipes.yaho...](https://web.archive.org/web/20150930021241/http://pipes.yahoo.com/pipes/)

[2] [https://github.com/ggaughan/pipe2py/](https://github.com/ggaughan/pipe2py/)

[3] [https://github.com/nerevu/riko/blob/master/docs/FAQ.rst](https://github.com/nerevu/riko/blob/master/docs/FAQ.rst)

[4] [https://github.com/nerevu/riko/blob/master/docs/COOKBOOK.rst](https://github.com/nerevu/riko/blob/master/docs/COOKBOOK.rst)

[5] [http://nbviewer.jupyter.org/github/nerevu/riko/blob/master/e...](http://nbviewer.jupyter.org/github/nerevu/riko/blob/master/examples/usage.ipynb)

<comment><USER2> Nice project. I wrote something similar in C# long time ago [1]. Mostly to monitor job feeds and craigslist [2] :-) It supports RSS and Atom, async, various filters, deduplication, etc

Yahoo Pipes was a nice project, but as its popularity grew, it started getting blocked more and more. It was also hard to build and maintain pipelines with more than a few steps.

[1] [https://github.com/olviko/RssPercolator](https://github.com/olviko/RssPercolator)

[2] [https://github.com/olviko/RssPercolator/blob/master/RssPerco...](https://github.com/olviko/RssPercolator/blob/master/RssPercolator.Client/Program.cs)

<comment><AUTHOR> Cool! I actually starred your project last year. Never really got around to looking under the hood though. How do you handle the "multiple destinations" part? In python you can do it with a coroutines [1, 2] implementation (push based). I avoided that, since it coroutines have their own form of callback hell, and decided to implement a generator api (pull based) [3, 4].

But since generators can only be "pulled" into one destination, you have to copy a stream (subsequently converting it into a list) if you want more than one destination [5]. This works fine if the data can fit in memory, but if it can't then you're out of luck!

[1] [http://www.dabeaz.com/coroutines/copipe.py](http://www.dabeaz.com/coroutines/copipe.py)

[2] [http://www.dabeaz.com/coroutines/](http://www.dabeaz.com/coroutines/)

[3] [http://www.dabeaz.com/generators/retuple.py](http://www.dabeaz.com/generators/retuple.py)

[4] [http://www.dabeaz.com/generators](http://www.dabeaz.com/generators)

[5] [https://github.com/nerevu/riko/blob/master/riko/modules/spli...](https://github.com/nerevu/riko/blob/master/riko/modules/split.py#L15-L18)

<comment><USER2> Can't really remember, sorry, that code was built for processing RSS feeds and data size was never an issue. I will take a look when get some free time…

But, I see what you mean. I had to deal with similar issues in commercial projects and the "pull" model (generators in Python ~ "yield return" in C#) almost never a good idea, especially when you have to have concurrent consumers. While callbacks are hard to combine, in C# it can be nicely abstracted with "async/await", not sure how it is handled in Python, I stopped using it around 2.5

<comment><USER3> Python 3.5 introduced the async/await syntax, I don't do C# but at a glance it's the same.

I've been working on a similar project and I've also found the push model easier.

<comment><AUTHOR> Care to share your code? I'd like to see a proper push implementation.

</comment></comment></comment></comment></comment></comment><comment><USER4> I was a heavy user of pipes and I'm now a heavy user of python. I have built my own dodgy simple replacement for some of the things I used to rely on pipes for. I'm very eager to see what you've got here, at first glance it seems like an excellent fit for my needs.

Thanks!

<comment><AUTHOR> Please let me know what you think. I worked pretty hard on the readme so let me know if anything is confusing and/or doesn't make sense.

<comment><USER5> This readme could be a guide for many projects!

</comment></comment></comment><comment><USER6> Can you consider Dask integration? [http://distributed.readthedocs.io/en/latest/queues.html](http://distributed.readthedocs.io/en/latest/queues.html) [https://github.com/dask/dask](https://github.com/dask/dask)

It can handle parallel and distributed parts for you.

[https://github.com/dask/dask](https://github.com/dask/dask)

<comment><AUTHOR> I just read about dask earlier today, very neat project! riko already handles parallel processing [1] but adding distributed processing sounds tempting. TBH though, distribution isn't high on the priority list. But I'll be happy to accept a PR if you are so inclined :)

[1] [https://github.com/nerevu/riko#parallel- processing](https://github.com/nerevu/riko#parallel-processing)

</comment></comment><comment><USER7> If you're looking for a stream processing engine more close to Storm, etc. but also simple, check out Motorway: [https://github.com/plecto/motorway](https://github.com/plecto/motorway) :-)

<comment><AUTHOR> Interesting project. I hadn't come across this one yet. One difference that riko has is it's based around functions whereas this library (and practically every stream processing lib I've come across) is based around classes.

I personally prefer the functional approach much better. And if you compare the word count examples on the respective readmes [1, 2], you will see riko is much more succinct. But I suppose the verbosity of the other libraries come with benefits like scaling across a cluster of servers.

[1] [https://github.com/plecto/motorway#word-count- example](https://github.com/plecto/motorway#word-count-example)

[2] [https://github.com/nerevu/riko#word- count](https://github.com/nerevu/riko#word-count)

<comment><USER3> I just started writing a functional stream processing library in Python for some of the same reasons.

We use somewhat different concepts. I tend to think of streams as infinite, so it didn't occur to me to include something like a reverse pipe operator.

I'm a bit surprised, why is filter an operator rather than a processor? I would think filters usually apply per-item, not to a whole stream?

I havn't worked on it very much but I'm heading towards push-based, using 0MQ for distribution/parallel processing, and using asyncio, mostly because it plays nicely with 0MQ.

<comment><AUTHOR> > We use somewhat different concepts. I tend to think of streams as infinite, > so it didn't occur to me to include something like a reverse pipe operator.

We are in agreement. reverse has a notice that it isn't lazy [1]. I prefer to include pipes that aren't lazy since it can be helpful in some cases (plus the goal is to include all pipes originally in Yahoo! Pipes). The vast majority of pipes work just fine on infinite streams [2].

> I'm a bit surprised, why is filter an operator rather than a processor? I > would think filters usually apply per-item, not to a whole stream?

Just an implementation detail [3]. I agree it would be better if it were a processor since it could be parallelized. PRs welcome :).

> I haven't worked on it very much but I'm heading towards push-based, using > 0MQ for distribution/parallel processing, and using asyncio, mostly because > it plays nicely with 0MQ.

See my previous comments related to this [4, 5].

[1] [https://github.com/nerevu/riko/blob/master/riko/modules/reve...](https://github.com/nerevu/riko/blob/master/riko/modules/reverse.py#L67)

[2] Assuming you're not using the async or parallel mode

[3] [https://github.com/nerevu/riko/blob/master/riko/modules/filt...](https://github.com/nerevu/riko/blob/master/riko/modules/filter.py#L141-L155)

[4] [https://news.ycombinator.com/item?id=12137591](https://news.ycombinator.com/item?id=12137591)

[5] [https://news.ycombinator.com/item?id=12137787](https://news.ycombinator.com/item?id=12137787)

</comment></comment></comment></comment><comment><USER8> I am still a user of Plagger [1], but development halted quite some time ago. Maybe this could be a good replacement.

[1] [https://github.com/miyagawa/plagger](https://github.com/miyagawa/plagger)

<comment><AUTHOR> Hadn't heard of this one before. There isn't a readme and the site seems to have been taken over. But from what I can tell based on the examples, it has a yaml based scheduler and does some pretty nifty things like IRC notifications.

riko doesn't have a scheduler (although the original pipe2py has a json based one). However, I do plan to integrate with Airflow/Oozie/Luigi [1-3] in the future to make it easier to design workflows.

The notification system reminds me of Huggin [4]. Since riko is twisted based, it should be fairly straightforward to implement something similar for IRC/IMAP/FTP/etc.

[1] [https://github.com/apache/incubator- airflow](https://github.com/apache/incubator-airflow)

[2] [http://oozie.apache.org/](http://oozie.apache.org/)

[3] [https://github.com/spotify/luigi](https://github.com/spotify/luigi)

[4] [https://github.com/cantino/huginn](https://github.com/cantino/huginn)

</comment></comment><comment><USER9> This is really interesting. Have you looked at Apache Beam? What I think is interesting about Beam -in this specific context- is that it has a standalone runner (java), that similarly as riko let you write pipelines without worrying about a complex setup. But then, if you need to scale your computation, Beam is runner-independent and you can take the same code and run it at scale on a cluster, wether it's spark, flink, or google cloud. You can read more here [1].

As for riko more specifically, Beam will have soon a python sdk, but I'm unsure if there will be a python standalone runner. Maybe this is something to look into...

[1] [https://www.oreilly.com/ideas/future-proof-and-scale- proof-y...](https://www.oreilly.com/ideas/future-proof-and-scale-proof-your- code)

<comment><AUTHOR> > This is really interesting. Have you looked at Apache Beam?

Just gave it a look. Took a while to find some examples with code, but once I did it made a bit more sense.

> Beam is runner-independent and you can take the same code and run it at > scale on a cluster, wether it's spark, flink, or google cloud.

I thought that was pretty cool.

> As for riko more specifically, Beam will have soon a python sdk, but I'm > unsure if there will be a python standalone runner. Maybe this is something > to look into...

A python standalone runner would be very useful. Otherwise I'm hesitant to go much further since my goal is to have a pure python solution for working with streaming data. Most libraries require installing java and that is what I'd like to avoid.

<comment><USER9> Python sdk is work in progress - there's currently a branch: [https://github.com/apache/incubator-beam/tree/python- sdk](https://github.com/apache/incubator-beam/tree/python-sdk)

</comment></comment></comment><comment><USER10> if someone can spin up a usable gui, charge enough to make a living without compromising on performance, promise some longevity and a way to export of my stuff I would probably pay for that, I loved pipes, the GUI was a big deal for me.

<comment><AUTHOR> Have you investigated any of the existing GUIs? [1-3] I'd love to hear your thoughts on their pros/cons. I do plan to integrate a nice GUI framework if I can find one.

[1] [https://azkaban.github.io/](https://azkaban.github.io/) [2] [https://developers.google.com/blockly/](https://developers.google.com/blockly/) [3] [http://nodered.org/](http://nodered.org/)

<comment><USER11> Node-RED is pretty great. I think a wiring interface is a better choice than a block-level thing like blockly.

<comment><AUTHOR> True, Node-RED is much more aligned to the original Yahoo! Pipes interface. I kinda like the scratch/blockly interface since you can make it clear which components can go where. Plus it's reminiscent of physical Lego blocks.

Which interface do you think is more newbie friendly? My gut says blocks (maybe something a bit more simple/refined than blocky) are easier to grok, while wires allow for designing more complex workflows.

<comment><USER11> I don't feel like blocks really maps well to the kinds of tasks i'd do in node-red and yahoo pipes, and presumably riko (I didn't dive too deep here yet though). a wiring interface better reflects the idea of inputs, filters, and outputs, and wiring them up in flexible ways. blocks seems a little rigid and more variable/iteration/function-based.

maybe figure out a few common workflows that people would make in riko or node-red, and mock up how they'd work/look in blocks vs. wiring/pipes.

<comment><AUTHOR> > maybe figure out a few common workflows that people would make in riko or > node-red, and mock up how they'd work/look in blocks vs. wiring/pipes.

Good idea, what are your workflows?

</comment></comment></comment></comment></comment></comment><comment><USER12> Sweet. I put together something similar for NodeJS which is now called 'turtle' (because it's turtles all the way down...). There's a bit of a focus on AWS Lambda & other FaaS solutions as a means of building Lambda architectures, but it can be used by itself.

[https://github.com/iopipe/turtle](https://github.com/iopipe/turtle)

<comment><AUTHOR> Reminds me of [https://github.com/node- machine/machine](https://github.com/node-machine/machine)

</comment></comment><comment><USER13> Looks interesting. What kind of applications do people use this for?

<comment><AUTHOR> Mashups [1] and Extract Transform Load (ETL) [2] are two big use cases. I developed a freelance project aggregator using an earlier version of riko [3].

[1] [http://mashable.com/2009/10/08/top- mashups/#0XwtqVCCXPq2](http://mashable.com/2009/10/08/top- mashups/#0XwtqVCCXPq2)

[2] [https://www.quora.com/How-do-ETL-tools-work](https://www.quora.com/How- do-ETL-tools-work)

[3] [http://app.kazeeki.com/](http://app.kazeeki.com/)

<comment><USER13> Thanks, appreciate your comment.

</comment></comment></comment><comment><USER14> While I didn't use yahoo pipes too often, I loved it. Having this as a python library (I'm trying to get deeper into python), is great! Kudos and good luck!

</comment><comment><USER15> Also in this space (and worth looking at for inspiration, especially for other potential sources and sinks of data) - Apache Camel [1].

[1]: [http://camel.apache.org/](http://camel.apache.org/)

<comment><AUTHOR> I don't know if it's bc of the language (java) or something else, but I've never been able to grok apache data projects. I theoretically know what they do, but there's no way I can understand the code, e.g. [1].

[1] [http://camel.apache.org/etl-example.html](http://camel.apache.org/etl- example.html)

<comment><USER16> The code you see in the beginnig is actually code for configuring a "route" from a source of data to a destination. That was for me the key to understanding it. Once you do, you will find the rest of the documentation easier to follow. The earlier versions of Camel put the config in XML filed, but most prefer the DSL approach

</comment></comment></comment><comment><USER17> Is there anything like this available that's based on node.js with a decent GUI?

<comment><USER18> [http://nodered.org/](http://nodered.org/)

<comment><USER17> This is amazing, thanks for sharing!

</comment></comment></comment><comment><USER19> Also might want to check out [http://concord.io](http://concord.io), it's a bit more work to set up, but it's much faster than most stream processing systems

<comment><AUTHOR> How does concord differ from the others? spark/storm/flink/etc...? Aside from being written in C that is.

<comment><USER20> eng at concord here.

Really cool API, you should port this to concord! =)

i'd say major diff is dynamic topology. So during the pipeline execution you can add/remove workers for any stage.

Also each stage/operator can be written in any programming language.

Storm/Flink/SparkStreaming/etc... all have much higher level API's. We built the execution engine first, these great things (DSL, etc) should come soon. For example this API would be easy to support to execute on top (the pipe abstraction that is)

Here is an example of a DSL we prototyped in a couple hours.

<comment><USER20> err. missing link:

[https://github.com/jjmalina/concord-python- dsl](https://github.com/jjmalina/concord-python-dsl)

<comment><AUTHOR> Pretty neat! I'm guessing that concord isn't limited to just map/reduce... correct? I think building in integrations to other systems in the stream processing ecosystem is key. First on the list is to integrate with popular workflow schedulers so that you can design topologies which riko would then parse.

Next up I think would be supporting custom sources/sinks such as Twitter, HDFS, RDMS, etc. What exactly would be involved in "porting" riko to concord and what would the advantages be for doing so?

<comment><USER20> Interesting, will keep an eye out as you mature it, looks like an awesome DSL for us to fill the runtime.

Advantages are:

1\. mesos integration, with that comes containerization support, multi tenancy, QoS, proper pipeline supervision, etc 2\. Scheduling of pipelines. i.e.: Schedule them on 100 computers. 3\. the outputs of your DAG could be consumed by other systems immediately and even written in different programming languages. So your python DSL could be the source to the Scala DSL at some point. so language interop 4\. Available KV storage 5\. Tracing (Zipkin) - ala Google Dapper. 6\. Fast networking - C++ backed runtime is 1 order of magnitude faster than the python one.

What would be involved, is not much from what I can tell.

Each concord 'operator' is like a networked function.

so given a DAG, you could generate many operators internally, or literally write them to a file, i.e.: operator_one.py etc. The code generation or internal scheduling would be the glue that's needed.

if you ever become interested, ping me! would love to collab email@example.com

</comment></comment></comment></comment></comment></comment><comment><USER21> This is absolutely beautiful. Love the fact that it's using RSS for this.

<comment><AUTHOR> Thank you. Apparently RSS never got the memo that it "died" ;).

</comment></comment><comment><USER22> Looks nice. Are there any plans for twitter support?

<comment><AUTHOR> Eventually. It would essentially be a "source" pipe. But ultimately, I want to build a plugin system so that end users can create/share their own pipes. I also plan to add pipes that let you add streams to a database.</comment></comment>


Customers ditch single-use coffee cups if sold separately - <AUTHOR> https://www.thetimes.co.uk/edition/scotland/customers-ditch-single-use-coffee-cups-if-sold-separately-0ngr7b5hr <comment><AUTHOR> > Four Scottish cafés trialled selling disposable cups separately from drinks. > They were asked to reduce the price of drinks by about 20p, the approximate > cost of a throwaway coffee cup. Customers were then charged 20p more if they > opted for a disposable cup.

I'm sceptical about this, I'd imagine different results if it were framed as 'save 20p if you bring your own reusable cup' (which Starbucks actually do, if it's one of their reusable ones) - I don't think as many would take it up.</comment>


Number plate cameras can tell an O from an 0. Drivers, can't - <AUTHOR> https://www.theguardian.com/money/2018/mar/16/parking-fines-number-plate-recognition-0-o <comment><USER2> That sounds more like a poor choice of font than anything.

<comment><USER3> [http://homoglyphs.net](http://homoglyphs.net)

<comment><USER2> License plates use a very limited set of glyphs.

There are plenty of programming fonts that make it trivial to distinguish the letter O and the number zero. Or distinguish uppercase i from lowercase L from the number one. Etc.

Arial is not one of those fonts.</comment></comment></comment>


Lisp is Abstract Syntax - <AUTHOR> http://michaelrbernste.in/2014/04/16/lisp-is-abstract-syntax.html <comment><USER2> I have yet to hear a good explanation why homoiconicity is a good thing or in any way easier to learn. My main problem is that you have to know all the same things, but they become unknown unknowns. Not being able to tell at a glance that the argument list in a lambda expression, as one of the most common examples, is doing something other than execute code is very confusing if you're expecting everything to follow the (func arg1 arg2) pattern. On the other hand, when you encounter different syntax, it's immediately obvious that you need to know something else - a known unknown, which is easier to correct.

<comment><USER3> Not everything is follwing a (func arg1 arg2) pattern.

For example a LET binding is following a (LET ((var1 binding1) (var2 binding2)) body) pattern.

<comment><USER4> Or in Clojure, I'm starting to accept that this common pattern is a good thing:

      (let [var1 binding1
            var2 binding2]
         body)

</comment></comment></comment><comment><USER5> _The abstract syntax was intended to be used writing programs until designers could get around to creating a concrete syntax with human-readable punctuation (instead of Lots of Irritating Silly Parentheses), but programmers soon got used to programming directly in abstract syntax._

That's _some_ programmers who got used to the syntax. It may be absolutely true that once you get used to LISP's syntax, it is better than any other. The problem is that since one is dealing with human beings, and with human beings you have the power of first impression and the tendency to make snap decisions based on these, people initial difficulty in grokking LISP's syntax is always going to be a hurdle for the language.

<comment><USER6> Is grokking Lisp's parenthesized s-expressions actually difficult though? I think that the real problem is that developers _believe_ that they will find it difficult before they try it, rather than _actually_ finding it difficult when they eventually do try it. I don't think I've ever picked up another class of languages faster; even python took more effort from me.

Basically, I think it's a marketing problem.

<comment><USER7> I have to respectfully disagree. I have coded for years in a lot of C-style languages, mainly C, Java, Python, Ruby & JavaScript and I've been struggling with the Clojure book (and various tutorials) for over a year. It's not just marketing, it's a very different mindset and one I'm not convinced is ever going to appeal to a large class of smart programmers (yes I guess I'm saying I don't think I'm dumb and hope I'm not alone in this feeling).

I've heard Lisp described as an autistic language, and I think there's something to that. I don't think it's for everyone. I'm not on board that macros, homoiconicity and some of the other stated benefits of lisps are worth 'giving up syntax' for and I am far from convinced that lisps are the future of programming.

I'm a huge fan of Rich Hickey and I want to love Clojure, I just can't. It's not for me and it's not a marketing thing. Rich is the best marketing a language could hope for.

<comment><USER8> I'm a fan of Rich Hickey, too. And I think Clojure is a solid language. But I wouldn't suggest Clojure as the entry point when seeking a overall understanding of Lisp. There's too much baggage and history swirling around it for explanations ever to be comfortable - e.g. even if Rich Hickey always makes convincing arguments, it's important to note that they are always arguments.

That is there always seems to be at least as much of a subtext of Clojure defining itself by what it isn't as an explicit statement of what Clojure is. So much of what is said about it is said in the context of "Clojure is not Java, or Haskell, or Scala, or Scheme, or Common Lisp" and because that is so much a part of its culture, it has details drawn from 'the best parts' of each and mashed up.

Like Common Lisp, it is a language for working programmers and will trade practical accretion over striving for internal conceptual consistency. Unlike Common Lisp or Scheme, it doesn't have the sort of simple core that lends itself to tutorials from first principles and even if it did, the community tends to be experienced where just jumping into the middle is more the norm.

That's nothing against Clojure. It's just that any sort of gentle introduction to Lisp is probably better sought in those places where it already exists - _SICP_ or the Racket ecosystem or _Practical Common Lisp_ or PG's _On Lisp_ are probably better introductions to what makes Lisp different. Clojure is probably a better second Lisp dialect for many people once they are ready for full tilt production code.

<comment><USER9> In learning Clojure first then Racket, it struck me how many good ideas came from racket.. and now how many are still being mined - typed racket being the obvious one.

<comment><USER3> I don't know how much Rich Hickey used Racket, but he used Common Lisp for several years and wrote some complex libaries for it. There is also a sketch of Clojure early on written in Common Lisp.

<comment><USER4> Racket started out as a Scheme, and Clojure has mined quite a bit from Scheme. Both are Lisp-1s, loop/recur, not accepting a lot of mainline LISP (e.g. Common Lisp nowadays) baggage, etc.

<comment><USER3> Actually there is not much Clojure got from Scheme. Lisp 1 is not tied to Scheme. loop/recur is much less powerful than Scheme's TCO.

<comment><USER4> Lisp-1 is pretty firmly tied in most people's minds to Scheme: at the very least the paper that coined the terms ([http://www.nhplace.com/kent/Papers/Technical- Issues.html](http://www.nhplace.com/kent/Papers/Technical-Issues.html)) ascribed it to Scheme, and as far as I know it first came from Scheme (although it's so easy to create a low performance Lisp I wouldn't be surprised if that had been tried before).

loop/recur is of course much less powerful than TCO, because the JVM doesn't natively support it (it's not trivial, security wise). There are three other Lisps on the JVM that I know of: SISC Scheme is mostly dead but does TCO at a cost in speed, Kawa Scheme has as of late added fine grain control over TCO, and Armed Bear Common Lisp doesn't try, as Common Lisps are not required to.

But loop/recur sure looks to be ultimately inspired by Scheme style use of TCO; I just did a set of functions using it for the first time and everything I learned from SICP/6.001 applied and made that part of it trivial.

<comment><USER3> Haskell also has only one namespace. I propose that Clojure took it from there, including persistent data structures, lazy data structures, ...

> But loop/recur sure looks to be ultimately inspired by Scheme style use of > TCO;

To me it looks more like ancient Lisp with prog and goto.

        (defun foo ()
          (prog ((a 1))
            start
            (print a)
            (when (< a 10)
              (incf a)
              (go start))))

Old Lisp code is full of that. It's basically what LOOP/RECUR provides.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER10> _The abstract syntax was intended to be used writing programs until designers could get around to creating a concrete syntax with human-readable punctuation (instead of Lots of Irritating Silly Parentheses), but programmers soon got used to programming directly in abstract syntax._

Perhaps it was, but..

1) The nature of research is so that you can't always predict in which way your invention will be useful. To me and many others it seems lisp syntax is quite handy.

2) If we take Clojure for the sake of example, we'd see that it comes with some neat macros which are important part of the language. Those can be viewed as mentioned concrete syntax elements built upon the abstract syntax. Punctuation's been improved as well.

</comment><comment><USER11> Well, yeah.

I think the popularity of lisp comes down to the hostility the mit ai lab had towards noam chomsky who in the 1960s spoke out about the vietnam war and thus bit the hand that funds cs research.

All other computer languages (except for forth) embraced formal grammar concepts but mit rejected them out of spite.

If mit had stopped burning the dragon book and embraced algol syntax we might have been spared the horrors of c, c++ and java but no, they just gave us 1 more reason rt 128 is a boulevard ofbroken dreams.

<comment><USER12> Huh. I was around the AI Lab in the late 1970s -- as an undergrad -- and I don't recall hearing anyone talk about Chomsky in the way you imagine. DARPA funding was still flowing rather freely, it seemed to me, well into the mid-1980s. I don't recall anyone suggesting that there would have been yet more DoD money if it hadn't been for Chomsky. And the grad student I did some work for, who was working on natural language parsing, was clearly intimately familiar with Chomsky's ideas on transformational grammar and referred to them throughout his dissertation.

So this isn't ringing true for me.

I also recall Gerry Sussman speaking quite highly of Algol 60.

No, I think you're quite wrong: the reasons for the popularity of Lisp at the AI Lab have to do with its actual advantages over other languages for the kinds of problems they were working on.

And there is an example of a language in the MIT tradition with infix syntax: Dylan. Great language, but wasn't in the right place at the right time to catch on.

<comment><USER4> Was Sussman talking about the syntax, or things like lexical scope, which he and Steele introduced to the LISP world with Scheme in the mid-70s?

About the only relevant negative thing I remember being said about Chomsky in a period just after your's was Marvin Minsky saying he saved someone from going down a rabbit hole following Chomsky's work. But that was a judgement of merit of his linguistics work, not his politics.

<comment><USER12> Well, the lexical scope, certainly, but I don't recall him disparaging the syntax.

I don't recall any burning of Dragon Books. Nor was Vaughan Pratt tarred and feathered for releasing CGOL, which allowed one to write Lisp in infix syntax. People were aware of it, and a few people used it, but it didn't catch on in a big way. I don't think this was for ideological reasons; I think it was simply that most people writing Lisp (myself included) found that _with proper editor support_ , editing fully parenthesized code is easy and pleasant -- _more so_ , in many cases, than editing infix code. That is the fact that many non- Lispers cannot believe could possibly be true. And yet over and over again, people who learn Lisp report that it is.

</comment></comment></comment></comment><comment><USER13> The biggest proof of the overwhelming preference for parens can be found in the dylan programming language. Despite having M-expression syntax (in fact, the original spec was prefix lisp), the same CLOS object system, and even a macro system, the language has gone nowhere with lispers. More interesting is that dylan was also unpopular with ALGOL programmers. The existence of "sweet expressions" (M-expressions) allowing infix syntax in existing lisp languages further removes this as the main issue.

The worst answer as to why people hate lisp is the "too many parenthesis" argument. C-style programmers are just as happy to mash 5-6 paren/curly-brace sets together in one line. The only major difference is location. For example, (if test (<result>) (<alternate>)) vs if(test){<result>}else{<alternate>}. In addition, the only reason the closing parens are on a separate line in C and the same line in lisp is convention.

I suspect the biggest barrier to ANY language is having a non-C syntax style rather than infix vs prefix or parenthesis. The inertia is simply too great.

</comment><comment><USER14> What I think this is missing which was a huge part of the SICP course is that Lisp is probably the best language to write your own language in with a custom syntax tailored for the problem space you're working on. Even if it isn't trivial to do.

An example is Clojure's Hiccup[0] where there's a whole new syntax for dynamic HTML generation. It's not a full new Turing-complete language, but it's a custom syntax and vocabulary that illustrates Lisp's extensibility (a sample of Hiccup in action is linked below, though it isn't mine.)

[0] - [https://github.com/yokolet/hiccup- samples/blob/master/src/hi...](https://github.com/yokolet/hiccup- samples/blob/master/src/hiccup_templating/views/contents.clj)

<comment><USER15> When I look at that sample, what strikes me is how much the "custom syntax" still looks like a bunch of S-expressions.

How much flexibility does LISP really give you here? For example, say I wanted my DSL to use Python-style significant whitespace instead of brackets. Does LISP make that easy, or is my DSL restricted to using stuff that looks like S-expressions?

<comment><USER6> Racket is somewhat unique in this respect, but it allows you to create dramatically different languages as DSLs.

Consider this example of the experimental "2d" syntax:

      #lang unstable/2d racket
      (require unstable/2d/cond)

      (define (same? a b)
        #2dcond
        ╔═════════════╦═══════════════════════╦═════════════╗
        ║             ║       (pair? a)       ║ (number? a) ║
        ╠═════════════╬═══════════════════════╬═════════════╣
        ║ (pair? b)   ║ (and (same? (car a)   ║     #f      ║
        ║             ║             (car b))  ║             ║
        ║             ║      (same? (cdr a)   ║             ║
        ║             ║             (cdr b))) ║             ║
        ╠═════════════╬═══════════════════════╬═════════════╣
        ║ (number? b) ║          #f           ║   (= a b)   ║
        ╚═════════════╩═══════════════════════╩═════════════╝)

Yes, that big ascii-art graph is actually part of the code, not some sort of comment. The 2d syntax allows you to create ascii art truth tables which contain in them code (in this case, in the traditional paren'd style.)

 _(See[http://docs.racket-lang.org/unstable/2d.html](http://docs.racket- lang.org/unstable/2d.html) for a better explanation and more examples.)_

Alternatively, here is an example of typed racket using sweet expressions:

      #lang sweet-exp typed/racket

      define: fact([n : Integer]) : Integer
        if zero?(n)
           1
           {n * fact{n - 1}}

_([https://github.com/takikawa/sweet- racket)*](https://github.com/takikawa/sweet-racket\)*)

</comment></comment></comment><comment><USER16> What most people have with Lisp syntax, I have with Objective-c. I am mostly blind to syntax (I skip from language to language fast reading/writing) except for some esoteric languages (like [http://www.hakank.org/k/](http://www.hakank.org/k/)) AND Objective-c. I find it extremely annoying to read while I do it every day. Writing is better for some reason, but far removed from other languages. So I see why some people would not like Lisp syntax while I find it very pleasant/enjoyable to read.

</comment><comment><USER17> "preventing advancement" is a pretty bold assumption.</comment>


Ask HN: Which engine do you use to develop indie games? - <AUTHOR>

I was reading about the Havok engine - http://www.havok.com/ and how its being used in advanced games, with super fast physics and rendering.<p>I was wondering which engine do game developers here prefer to get started quickly. Any suggestions or recommendation? Thanks in advance. <comment><USER2> Have you used game engines before? If not, pick one, and use it to make a game or two. Then you'll know what you want/need in an engine.

Most game engines are amazing and you could rarely go wrong. The trick is that you should not compare tools too much. Go make the game. Use whatever. Be awesome.</comment>


Blockstack Whitepaper: A New Decentralized Internet (Part I) - <AUTHOR> https://blockstack.org/blog/blockstack-whitepaper-part-1 <comment><USER2> > Blockstack solves the bootstrapping of trust problem by leveraging the most > secure public blockchain.

i.e., Bitcoin, which is not named at any point. This seems odd.

<comment><USER3> Thanks for pointing it out. Bitcoin is referenced in the whitepaper and made it clear in the blog post as well. (Don't want the readers to get confused between the virtualchain blockchain and the Bitcoin blockchain that is used underneath.)

</comment></comment><comment><USER3> The title of this post should probably be updated to "Blockstack Whitepaper: A New Decentralized Internet (Part I)" to match the blog post title.</comment>


Android banking malware is on Google Play over month with over 10,000 installs - <AUTHOR> https://lukasstefanko.com/2018/10/android-banking-malware-found-on-google-play-with-over-10000-installs-targets-brazil.html <comment><USER2> The Android ecosystem today is like Windows circa 1998-2002, even with the Play store. It's now fairly reasonable to assume that every app has a high likelihood of containing malware.

The safest bet is to avoid installing any software, especially random little games and utilities. You probably don't need them, and they're definitely not worth the risk.

<comment> saiya-jin You're probably right many apps are not worth the risk, but I use quite of few single-purposes apps, my phone would be semi-useless brick without them and I can buy old school Nokia for just calls and SMS.

Heart rate (from optical sensor), free topo maps for outdoor, various transport apps (checking when buses/trams will go realistically based on their GPS), car navigation, watching BBC news, translate, use a freakin' calculator, browse phone file system, control my A/V receiver over wifi. And so on and on.

For every app removed I would lose an useful functionality that helps me quite often, for some there ain't any good replacement.

I think smarter is to not any sensitive data in the phone, consider it hacked out of factory and act accordingly.

<comment><USER3> Try Lineage on a phone with F-Droid as your app repo: much more trustable - though not completely, plenty of blobs floating around, the modem OS, and is safe to assume there are non-public bugs out there. Also, none of the crappy preinstalled apps, no google spyware, no touchwizz madness - just a clean, vannila Andoid experience, just as the original developers intended.

<comment><USER4> I have gotten Lineage going on a couple of older phones for friends, I am skeptical that it and F-droid are inherently much more safe than stock + the Play Store - except that they're less tempting targets for exploitation. Which I suppose is worth something, still.

</comment></comment></comment></comment><comment><USER5> The situation on Google Play is getting serious, just check out the author's twitter account. Every day several apps are detected, and this is probably just a small part of the total number. There are also lots of fake apps that don't do anything (RAM increase, battery repair, ...) and either contain malware or at least they bombard you with ads (or make fake clicks on ads).

</comment><comment><USER6> I work at an AT&T store, we get people in everyday with phone issues related to all the advertising apps. People will have basically non responsive phones where you have to swipe through 8-9 different lockscreens just to get to the home screen. Not once has an ios user ever come in with the same issue, the play store is just a joke. [https://play.google.com/store/apps/details?id=com.smartkeybo...](https://play.google.com/store/apps/details?id=com.smartkeyboard.emoji&hl=en_us) is a huge culprit on most of the phones that come in. The Emoji keyboard changes your launcher and does nothing but spam you with nonstop ads. That it has such a high rating despite so many 1-2 star comments talking about how it ruins whatever phone it touches shows you how messed up the play store is.

</comment><comment><USER7> I remember when Fortnite came out on fortnite.com instead of the Play Store, and everyone was writing articles about how likely it was people would get malware if they weren't under the safe and snug umbrella of the Play Store. Turns out those were all just about the 30% cut Google didn't want to lose.

The safest way to get an app is from the official website of that app. If they link you to an app store to download it, presumably they're providing the proper actual package name ID that's unique and published by them.

</comment><comment><USER8> Play Store security is a joke. A few weeks ago I shipped a new app to it, expecting a review process that would last hours or days. It was accepted and made live in less than an hour. Should I really believe that this thing was thoroughly scanned or so much as glanced at by a human being?

<comment><USER9> What analysis can you run in a day that you can't run in an hour? If your app didn't trip any alarms, why would you expect a human to review it?

</comment></comment><comment><USER10> :') no suprise. next up, apple store ;) ... oh wait, it's not malware if it's signed by apple ofcourse :'D ...</comment>


"I don't know if DiagTrack and the service are one thing." - <AUTHOR> https://twitter.com/BrandonLive/status/906566094864842752 <comment><AUTHOR> Notice no response even a week later.</comment>


Leading elephant conservationist shot dead in Tanzania - <AUTHOR> https://www.theguardian.com/environment/2017/aug/17/leading-elephant-conservationist-ivory-shot-dead-in-tanzania <comment><AUTHOR> You guys should consider donating to anti poaching foundation [https://www.iapf.org](https://www.iapf.org) that does a great job fighting these poachers. There's also David Sheldrick Wildlife Trust which takes care of elephant and rhino orphans [https://www.sheldrickwildlifetrust.org](https://www.sheldrickwildlifetrust.org). Most of them are orphaned due to poaching

<comment><USER2> Daphne Sheldrik do really good work. They also it effort into training people I rather than importing them.

</comment></comment><comment><USER3> Oops! The poachers basically opened the season on themselves.

After this, no radical conservationist on the planet is going to have any lingering shred of remorse in going after their lives.

<comment><USER4> Hopefully they still will. An eye for an eye leaves everyone blind.

The sweet spot for deterrence comes in the form of punishment that is swift and certain, not necessarily dire.

<comment><USER5> I'm sorry, no. I must respectfully disagree here - death to poachers is fair when we're talking about the extinction of species, and certainly of some of the most majestic creatures on our planet. We have 7+ billion humans and fewer than 500 thousand elephants in Africa and fewer than 30,000 rhinos left. They are more valuable than gold - literally priceless. Everything and anything must be done to protect and ensure the survival of the species.

<comment><USER6> > Everything and anything must be done to protect and ensure the survival of > the species.

That's _your_ value judgement. Others may have a different judgement. How do you decide who's right?

(Just for clarification: I think poachers are the scum of the earth, but there's a long way from that to what you're proposing, AFAIUI.)

</comment></comment></comment></comment><comment><USER7> This is incredibly sad news. My thoughts are with his family. What a sad world we live in sometimes.

<comment><USER8> I agree. But man, what an incredible world we live in that we have people literally willing to put their life on the line for causes like this.

</comment></comment><comment><USER9> sad but the reality is that if you're going to cost organized criminal groups millions of dollars...you risk your life. Just business, and life is pretty cheap in some parts of the world.

<comment><USER10> I agree with the sentiment that there are systemic problems. But I disagree with tone of resignation.

<comment><USER2> I feel like growing up in that environment breeds résignation around the frankly pretty common deaths that crop up.

</comment></comment></comment><comment><USER11> i recently went on my first safari in Sabi Sands in South Africa. It was an incredible experience. I intend to see more of Africa. Hopefully, enough tourism to Africa will encourage more protection of the animals. Riding around in an open jeep taking pictures like these is a unique experience:

[https://www.instagram.com/p/BVrIQXLF1uF/?taken- by=mmellinger...](https://www.instagram.com/p/BVrIQXLF1uF/?taken- by=mmellinger66)

[https://www.instagram.com/p/BVtxGoVlh6E/?taken- by=mmellinger...](https://www.instagram.com/p/BVtxGoVlh6E/?taken- by=mmellinger66)

[https://www.instagram.com/p/BVty4K8FjBG/?taken- by=mmellinger...](https://www.instagram.com/p/BVty4K8FjBG/?taken- by=mmellinger66)

[https://www.instagram.com/p/BVtyQxHFYCa/?taken- by=mmellinger...](https://www.instagram.com/p/BVtyQxHFYCa/?taken- by=mmellinger66)

<comment><USER12> Safaris are a great experience, but if everyone starts doing them, there are certainly some ecological problems. It needs to remain the fun for the few rich and privileged.

<comment><USER13> From my experience visiting Kruger earlier this year, the overcrowding problem is fixed by simply closing the gate after a certain quota is reached. I was there during a local holiday and they closed the gate at around 11am as enough people entered already by that time.

I'm not sure if I'm confusing what you mean with 'Safari' with something else, but entering the park and driving around to spot and see wildlife, is not that expensive. Entrance to Kruger is under 5euros for South Africans for instance, definitely not for the rich and privileged only.

<comment><USER12> You are right of course, a safari is not that expensive once you have traveled to the place. I myself was 3 weeks ago on a one-day trip from Johannesburg to Pilanesberg. The cost was USD 250 for a trip for two people, with pick-up from hotel, transport, entrance to park, game rides, lunch and drop back to hotel. Anyone who can afford to travel to Johannesburg from Europe, Asia or America can afford that.

The ride around the park is not that bad for nature (it's on roads built around the area, no-go outside vehicles) but if the number of visitors increases a lot, I can see the pressure definitely is a problem (more and more people want to come, so maybe the gate needs to be open for a few more people? And so on.)

I saw many of the impressive big animals there, elephants, giraffes, zebras, GNUs, etc, and to top it all, a leopard waited behind a bend on the road, and walked right next to our jeep so that we could just observe it. It was not bothered by our jeep at all. Even cell phone camera pictures are very good.

It was great to see it. But somehow I felt not comfortable about it. Why's that great animal not afraid of people that drive this ugly jeep right next to her hunting grounds?

<comment><USER13> In 5 days I found only one leopard, and it was fairly distant, I'm glad you could see one up close!

I understand the pressure factor you mention, but at the same time I don't think that making it an exclusive expensive experience only for a few is really a solution (as parent was hinting to). One possible solution that comes to mind is Machu Picchu: you want to go there? You need to buy a ticket months in advance.

About your last comment, on why are animals not afraid of us: I've been talking with a Park Guard, and he mentioned that people in cars are not seen as humans but as a big harmless object moving. When in a car we are just like other animals. Once you are out of the car the scenario completely changes as you are identified as human and animals either move away or charge you. It kind of all made sense once I took a walking tour in the park, and I could clearly see that animals were moving away as we were approaching, keeping a very large distance between them and us. Not sure what's the percentage of truth in this but it makes quite some sense.

<comment><USER12> Yes, that "they think cars are just big harmless animals" is of course what everyone says. But still I somehow felt it wasn't right.</comment></comment></comment></comment></comment></comment>


Amazon Macie: A machine learning service to discover and protect sensitive data - <AUTHOR> https://aws.amazon.com/macie/ <comment><USER2> Important to note that the classifier only looks at the first 20MB of each object, so it might miss sensitive content in large files.

[https://aws.amazon.com/macie/pricing/](https://aws.amazon.com/macie/pricing/)

</comment><comment><USER3> I wonder if this is the same service that they use to scan public Github repositories for Secret AWS keys. I'll admit that I've accidentally committed a private key to a public repo before, and I received an email from AWS letting me know about it shortly after.

I suppose that its in Amazon's best interest to not have people hacking accounts and spinning up the maximum amount of EC2s to mine Bitcoins.

<comment><USER4> Not for Github, but the TruffleHog project on GitHub might be of interest to you. There is also SourceClear, which does the same for secrets in GitHub.

Note - AWS is monitoring AccessKey use and API thresholds to keep you informed.

</comment></comment><comment><USER5> Looks like Macie was originally developed by harvest.ai before they were acquired by Amazon last year.

[https://techcrunch.com/2017/01/09/amazon-aws-harvest- ai/](https://techcrunch.com/2017/01/09/amazon-aws-harvest-ai/)

<comment><USER6> >The San Diego-based startup, co-founded by a team that includes two former NSA employees

>Harvest.ai's flagship, patent-pending AI product is called MACIE Analytics. It uses AI to monitor how a customer's intellectual property is being accessed in real-time, assessing who is looking at, copying or moving particular documents, and where they are when they're doing this, in order to identify suspicious patterns of behavior and flag potential data breaches before they've taken place. It bills the service as a way to combat the risk of insider attacks.

did they get the idea after seeing what happens at NSA with contractors/whoever downloading data to wherever?

<comment><USER7> Or after seeing Veritas Data Insight? [0]

Data insight is targeted at more user oriented unstructured content repositories (CIFS, NFS, SharePoint, OneDrive, SharePoint Online, Box), but the fundamentals are very similar: content classifiaction, data profiling, risk scoring, access pattern anomaly detection, access control remediation.

[0] [https://www.veritas.com/product/information- governance/data-...](https://www.veritas.com/product/information- governance/data-insight)

</comment></comment></comment><comment><USER8> Classic, selling the poison and the cure. Access controls shouldn't be so convoluted and opaque that it requires a separate service to analyze your configurations. Crazy that we've made such a mess of the security landscape that we need _AI systems_ to tell us if we're leaking info.

<comment><USER4> Not the case. I've seen seasoned developers (not to single them out) make simple stupid mistakes with the S3 bucket ACL, Permissions, and Policies. The issue has to do with the sheer laziness of "let's create unstructured data buckets, write once and forget it all" mentality. At some point, this sort of service can be useful in identifying the "crown jewels" within the buckets. Beyond that, the ACL is noAccess by default, so I can't agree with your assertion that AWS is somehow making it difficult to sell more services in favor of vendor lockin.

<comment><USER9> Just a day or two ago on HN... [https://github.com/eth0izzle/bucket- stream](https://github.com/eth0izzle/bucket-stream)

<comment><USER4> Yes, thank you for linking, but fail to see the correlation. This tool is scanning public HTTPS endpoints based on keywords in its dictionary to discover misconfigured buckets. AWS doesn't manage the bucket Perms/ACL, the customer does. AWS' shared-responsibility model clearly defines all of this. The customer is responsible for the bucket ACL, the same would apply if I ran my stack in a data center and went on to configure Apache/NGNIX with open Directory indexes that allowed anyone to traverse them.

</comment></comment></comment></comment><comment><USER10> Previous Discussion: [https://news.ycombinator.com/item?id=15012225](https://news.ycombinator.com/item?id=15012225)

</comment><comment><USER11> The S3 data classification seems too expensive, but if the Cloudtrail stuff works, that seems pretty cheap for what you get.

<comment><USER12> CloudTrail is indeed very cheap for customers — we record nearly all API calls and access to AWS resources and deliver these events to our subscribing customers. And the events are delivered for free, outside of S3 and Lambda "Data events" — gets, puts, and function invocation is billed at a very cheap rate.

(We recently released our AWS Lambda integration — you can now record all Lambda function invocations with us!)

Disclaimer: I'm a Software Engineer with the AWS CloudTrail team.

<comment><USER11> If I'm reading this right, you now have two paid services for detecting CT anomalies: Guard Duty, which is nosebleed expensive, and Macie, which is practically free. What's the difference between the two?

<comment><USER13> Macie Analayzes a subset of CloudTrail, not all actions and is about historical behavior (though for high sev actions, it is more point in time)

GuardDuty is looking for specific threats/attacks and can combine multiple sources of telemetry for more advanced correlation. E.g. A combination of VPC Flows + CloudTrail + DNS that trigger an alert when formed together while a single CloudTrail event may not have.

<comment><USER11> Within CT, what are examples of things Macie will catch, vs. things you'd need GD to catch?

If GD weren't so expensive, I wouldn't really care that much. But GD is so expensive that it can be hard to recommend, which is especially weird since the pricing for Macie CT is so low --- even weirder when you note that the pricing for Macie S3 is so high!

<comment><USER13> I found the pricing for Guard Duty reasonable compared to most IDS systems.

They let you turn on GuardDuty for free for 30 days and give you an estimate your bill so that helps.

</comment></comment></comment></comment></comment></comment><comment><USER14> How does this compare to Google's Data Loss Prevention?

<comment><USER15> Google's Data Loss Prevention is provided on G Suite and Google Cloud Platform (GCP). Both products use the same unified classifier codebase. G Suite DLP allows admins to enforce policy on Gmail and Drive files. On GCP, the Data Loss Prevention API allows developers to classify and redact sensitive data in virtually any data source in real-time or at-rest (e.g. Google Cloud Storage, BigQuery, AWS Redshift, AWS S3, Salesforce, Slack, on-prem, custom apps, etc.).

DLP API scans are not limited to 20MB and can scale up to virtually any size. API results can be used for programmatic automation of alerts, IAM/ACL settings, or other remediation and can be sent automatically into BigQuery for detailed analysis or reporting. In addition to classification, Google's DLP API provides data masking tools for structured and unstructured data including format-preserving encryption, bucketing, and tokenization. This helps developers reduce unnecessary PII when collecting, storing, or sharing data.

(Note: I am the Product Manager for DLP API at Google Cloud)

</comment></comment><comment><USER16> Waiting for it (and many more services) to become available in ap-south-1.

</comment><comment><USER17> jeff bezos's own personal dashboard to exfiltrate warez</comment>


Show HN: a showcase of our local tech community in Playa del Carmen [d3.js] - <AUTHOR> http://techplaya.com

<comment><USER2> Sounds like a great place to work! Just to let you know, the Fahrenheit mode of your climate graph is broken, shows the same value for both the mins and maxs</comment>


Pampy: Pattern Matching for Python - <AUTHOR> https://github.com/santinic/pampy/blob/master/README.md <comment><USER2> Just a quick FYI, but in vanilla Python 3 [1] you can already do a head/tail split on any iterable:

        >>> hd, *tl = range(5)
        >>> hd
        0
        >>> tl
        [1, 2, 3, 4]

[1] Tested on 3.6.5, don't know about older versions

<comment><USER3> This is due to PEP 448 "Additional Unpacking Generalisations" [1], which was approved with effect from Python 3.5. Other examples:

        x, y, *r, z = range(7)
        print("x: {}, y: {}, r: {}, z: {}".format(x, y, r, z))
        # prints: x: 0, y: 1, r: [2, 3, 4, 5], z: 6

        x, (qa, *qr), *r = [1, [2, 3, 4], 5, 6]
        print("x: {}, qa: {}, qr: {}, r: {}".format(x, qa, qr, r))
        # prints: x: 1, qa: 2, qr: [3, 4], r: [5, 6]

The same PEP allows expanding lists and dictionaries in literals:

        r = [*r1, *r2]    # Same as r = r1 + r2 if they are lists
        d = {**d1, **d2}  # Merges d1 and d2 into d

[1] [https://www.python.org/dev/peps/pep-0448/](https://www.python.org/dev/peps/pep-0448/)

<comment><USER3> I was mistaken, sorry. Those unpackings work as of Python 3.0 due to PEP 3132 "Extended Iterable Unpacking" [2]. PEP 448 is just for those examples in the second half of my comment.

[2] [https://www.python.org/dev/peps/pep-3132/](https://www.python.org/dev/peps/pep-3132/)

</comment></comment></comment><comment><USER4> One of the very reasons why Haskell and Rust are so safe is because pattern match checking in these languages is exhaustive. If you don't cover every possible type constructor for an enum or pattern the compiler will throw an error.

For example, the Maybe monad used with match must have Nothing and Just handled during pattern matching. Precompile time logic checking.

The below will throw a precompile time error:

      handleMaybeNum :: Maybe int -> int
      handleMaybeNum Just a = a

The below will not:

      handleMaybeNum :: Maybe int -> int
      handleMaybeNum Just a = a
      handleMaybeNUm Nothing = -1

Could the same be said for this library? If so when combined with mypy type checking and functional programming this can transform python into a language with haskell level saftey.

<comment><USER5> What's the theoretical difference between this kind of pattern matching and polymorphism? Instead of encoding the logic for each branch in a switch, do we get the same kind of exhaustive static guarantees if instead we encode each branch as a polymorphic implementation on each type?

For example, Java's Optional type seems to provide the same static guarantees without pattern matching (assuming it didn't have the unsafe get() method).

<comment><USER6> You are right assuming the more or less equality between two approaches.

For example, you can encode Just as fJust :: a -> (a -> b) -> b and Nothing as fNothing :: b -> b. fJust receives a computation that accepts argument of Just constructor, while fNothing receives just a value to be returned. Or, alternatively, you can look at the type of maybe function which is pattern matching on Maybe in disguise: maybe :: b -> (a -> b) -> Maybe a -> b.

(I believe this method is called Church encoding)

But when you go from structure of types and patterns to functions, you lose the ability of analysis (of exhaustivity or anything else). You now deal with something that is Turing complete instead of fixed size structure.

And this is delimition of "possible" and "impossible". With the Church encoding analysis of matching completeness is impossible and even writing matchers for lists or trees is nigh to impossible, actually.

<comment><USER7> I believe this is actually Scott Encoding.

</comment></comment></comment></comment><comment><USER8> Looks neat! Pattern matching is one of those features that I sorely miss when I have to program in Python.

I do feel a bit wary seeing this[1] though, given that `_` can be considered a special character in Python. I suppose you can use `ANY` instead of `_` in the pattern matches, but of course that would not look as clean.

[1] [https://github.com/santinic/pampy/blob/4c8e6e0cabada82a5ed79...](https://github.com/santinic/pampy/blob/4c8e6e0cabada82a5ed794f935e9a6d249d2833a/pampy/pampy.py#L9)

<comment><USER9> I agree. Lots of Python programmers use "_" as a variable name to indicate (by convention) that they don't intend to use the variable yet are syntactically required to give it a name[1]. Some common examples:

        for _ in range(10):
            ...

        red, _, _ = rgb(color)

        first, *_, last = some_list

This convention conflicts with the use of a global variable named "_" because the first time a programmer uses this convention and rebinds "_" to something arbitrary it will mask the "_" imported from pampy. Of course a programmer is free to give it a more conventional name:

        from pampy import _ as placeholder

But for my money pampy should have given "_" a real name and left it up to the programmer to give it a short alias if so desired:

        from pampy import placeholder as _

This is in line with common conventions around say, numpy, which is conventionally aliased to the shorter "np" on import:

        import numpy as np

[1]: [https://stackoverflow.com/questions/5893163/what-is-the- purp...](https://stackoverflow.com/questions/5893163/what-is-the-purpose-of- the-single-underscore-variable-in-python)

EDIT: So it turns out that pampy _already_ has a more explicitly named alternative to "_" called "ANY". So anybody who doesn't like the _ syntax can use "from pampy import ANY" and use that instead.

</comment></comment><comment><USER10> And here is an another pattern matching implementation for Python [1]. It was made for compilers construction task and may look similiar for those who has an experience with Prolog, Stratego or Refal.

And here is a toy term rewriting system [2].

[1] [https://github.com/true-grue/raddsl](https://github.com/true-grue/raddsl)

[2] [https://github.com/true-grue/code- snippets/blob/master/ttrs....](https://github.com/true-grue/code- snippets/blob/master/ttrs.py)

<comment><USER11> > And here is an another pattern matching implementation for Python [1].

Oh, I like the prettier syntax:

        calc_rules = alt(
          Int(id),
          rule(BinOp("+", Int(X), Int(Y)), to(lambda v: Int(v.X + v.Y))),
          rule(BinOp("-", Int(X), Int(Y)), to(lambda v: Int(v.X - v.Y))),
          rule(BinOp("*", Int(X), Int(Y)), to(lambda v: Int(v.X * v.Y))),
          rule(BinOp("/", Int(X), Int(Y)), to(lambda v: Int(v.X // v.Y)))
        )

([https://github.com/true- grue/raddsl/blob/master/examples/cal...](https://github.com/true- grue/raddsl/blob/master/examples/calc/calc.py))

This way of sharing variable names between the pattern and the associated action is pretty neat. It's much nicer than Pampy's use of '_' for all variables.

</comment></comment><comment><USER12> There is also a JavaScript port of this library, by the same author: [https://github.com/santinic/pampy.js](https://github.com/santinic/pampy.js)

</comment><comment><USER13> It's neat that Python allows writing such things, but it'd be nice to see what the effect on debugging and stack traces are before writing anything with it.

<comment><USER14> Pattern matching is actually not very hard to write. There is a portable pattern matcher for scheme that uses macros to provide high quality code generation.

In guile the module (ice-9 match) generally has zero runtime cost compared to equal hand-written code.

<comment><USER13> This may be true but misses my point: when I navigate a stack trace and try to figure out how execution went through this match process, it will be more difficult to understand than idiomatic Python code, because the tooling is line-oriented.

Good FP debuggers would be able to step through it of course so it can be restated as a "toolchain issue" but that ignores the fact that Python is largely statement oriented, in terms of its execution model.

<comment><USER14> Sorry, I should have been clearer. The macro way of doing it doesn't mess with stack traces as it expands to pretty clean scheme code, at least after the optimizer has had it's way.

I am sad that most languages don't have macros since it is a very powerful tool. Not only does it let you abstract the ugliness away from approaches like this python one (which is actually pretty decent), but it also let's you produce good machine code from a "bolted on" construct. The python matcher is bound to have some overhead, whereas a syntactically expanded one is not.

<comment><USER13> Ah I see what you mean (I wrote macros in Clojure years ago). Yep that would do it, but would require an AST-rewriting decorator in Python.

<comment><USER15> That's an interesting thought! I guess I just found a good project to play on during the holidays. I wonder if something like this would work:

        with matching(expr) as m:

            @m(pattern)
            def do_for_pattern(v):
                ...

            @m(_)
            def catchall(v):
                ...

<comment><USER16> Something like this?

      class matching:
          def __init__(self, expr):
              self.expr = expr
              self.patterns = []
              self.result = None

          def __call__(self, pattern):
              def _inner(func):
                  self.patterns.append((pattern, func))
                  return func
              return _inner

          def __enter__(self):
              return self

          def __exit__(self, *args):
              for pattern, func in self.patterns:
                  if pattern.match(self.expr):
                      self.result = func(self.expr)

</comment></comment></comment></comment></comment></comment></comment><comment><USER17> Nice! Extending this further to support associative and commutative operations yields a functionality similar to that provided in Mathematica. This approach was taken by the MatchPy project to hopefully integrate into SymPy so that they can use the Rubi integration ruleset.

</comment><comment><USER18> Oh my god, I was just considering building exactly the same thing for my project. Thanks a lot :)</comment>