Mathematician (optimization) turned software engineer, 5+ of experience. I believe that with good mathematical models we can ship better code and products. I have good experiences doing front-end development but I am a better backend developer. I have a slight bias to functional programming. I pride myself on shipping products that our users have loved. If you work on a domain with good data, I would love to take a look.
Mathematician (optimization) turned software engineer, 5+ of experience. I believe that with good mathematical models we can ship better code and products. I have good experiences doing front-end development but I am a better backend developer. I have a slight bias to functional programming. I pride myself on shipping products that our users have loved. If you work on a domain with good data, I would love to take a look.
this is an interesting observation. I have various explanation on why that might be the case.
on a commercial setting there is more pressure to deliver code then to review it. combine it with the lack of our benevolent dictator for life (that has been on the project the world life cycle, not just recently), there is no one with power to actually say no to changes.
language geeks are novelty seekers. they will use every feature of their language . stronger languages have more features to abuse. so on a commercial setting you will have all the features being used without much thought an architectural design that says you that no, we shouldn't do that.
that's also why I think projects with benevolent dictators for life on the open source ward don't fall these in paths even though they use languages that are stronger.
you could restrict yourself to use languages that have only one way to be used, so python as it was originally. or use a language little abstraction power. but you will suffer in other ways. as abstraction power is genuinely useful. accidental complexity has a way of getting in by expressive means or by social means.
Yep. Even with "old drugs" the new programs using those give significantly better chances than with the old programs. Year of data collecting sure have given results.
I had testicular cancer in 2006 in Chile. I was a teenager so I went with the public system (AUGE back then). My parents friends were giving the condolences for my soon to occur death. The doctors had a laugh as in the last 10 years (by then) my chances of dying of it became basically nil.
Last year we hired a new guy at $JOB that 1 week after being hired was diagnosed with testicular cancer too. He really thought he was gonna die. He was at stage 4 (which is a highly zone specific metric). Last time I saw him he is still coding and more bald. It was more difficult to sort payments than the treatment as he is in the US.
Most testicular cancer is now reliably curable by harsh but effective chemotherapy. Mission accomplished? Not quite. Curative drugs such as cisplatin are scarce. Their patents are long-expired, so they're less profitable to manufacture, so manufacturers don't manufacture them. Hooray for the free market.
> It's because it's objectively harder to reason about performance with lazy evaluation as performance becomes non-local.
This is off-repeated, but has two interpretations. If you mean performance as in number of steps needed to reduce an expression, lazy evaluation is superior to strict evaluation. If you mean the indirection needed to access a thunk, well someone -- either the producer (strict) or the consumer (lazy) -- had to do that anyways. If GHC can determine that the demand for the value is strict, it won't generate the thunk in the first place. Instead it will provide a specialize calling convention via the worker/wrapper transform, which is standard. On the un-optimized case we still have dynamic pointer tagging (which is a transgression on the T of the STG machine) which serves as a tag to check whether we are dealing with a value or a thunk quickly. So if by non local performance you mean the indirection, modern GHC shows that is not true.
If you means that space leaks are a non-local property and they affect performance, well you are sort that right. But as with all programming, we have defensive patterns against that.
There are 2 types of space leaks: liveness leaks and strictness leaks. Only the first one are a non-local property, ie the appear as a consequence of the composition of different code pieces. But given the default purity of Haskell, those can only appear on long lived data references with are syntactically marked by:
- IORef, MVars, TVars
- get/put pairs over a state environment
So what you do is to specify in the types that values stored on those environments are to be evaluated before being stored, so references don't leak. I speak about this on this
This reply neatly captures that functional programming tends to consider performance/efficiency in terms of number of reductions. Sadly other programmers tend to view it as wall clock time and the two don't correlate very well.
If a client comes to me and says one of the parts of their application was slow, and I come back to them saying I lowered the number of reductions with zero change in the wall clock time, they'll fire me, and rightly so.
To be nitpicky, wall clock time isn't the same as CPU time or power draw. You can increase efficiency at the same time as you increase wall clock time because they aren't necessarily the same metric.
I think you're overcomplicating this. In a language with lazy evaluation, you can't know what gets evaluated without looking at the whole program (in the worst case). It's in that sense that performance becomes non-local.
Here's a simple specific example. Take the Haskell expression [1..n], for some big n. There is no general answer to the question "what would be the performance implications of replacing [] with [1..n]" – it depends on the context of [].
In a strict language, you can say (roughly at least) that replacing [] with [1..n] will add at minimum a certain number of extra CPU cycles and a certain amount of additional allocation. This kind of reasoning is pretty rough and ready, but it is accurate enough to be useful for reasoning about performance in practice.
I note that Simon Peyton-Jones has said these exact words in a public talk:
"Laziness makes it much, much harder to reason about performance."
I think it's extremely unlikely that he's mistaken or confused on this point.
> In a strict language, you can say (roughly at least) that replacing [] with [1..n] will add at minimum a certain number of extra CPU cycles and a certain amount of additional allocation.
It's not at minimum, it's always the worst case cost of N in strict languages, whereas the lazy setting provides you with amortized complexity.
I think you might be misunderstanding what I meant by "at minimum". I'm talking about the case of replacing a [] constant in some arbitrary piece of code with something like [1..10000]. Given strict semantics you'll of course incur at least the time and space costs associated with constructing the list (that's the "at minimum" bit), but you might also incur additional costs depending on what the rest of the code does with the list. For example, it might execute some arbitrarily expensive computation if the list has more than 20 elements, or whatever.
I think you might have thought I was saying that given a strict semantics it was somehow still possible that you wouldn't necessarily incur the full time and space penalty for constructing n elements (which of course is not the case).
Interesting comment, but many parts of it flew over my head. Would you by chance have some suggestions on where could I better my knowledge of Haskell internals/FP runtimes? Of course your blog has been added to my to-read list :)
I used to know Haskell to an “intermediate level”, but haven’t used it in years, but I am more familiar with “traditional” runtimes/compilers, like the JVM as a reference.
I am a (applied) mathematician turned software engineer. I have worked at backend services and iOS apps. I have some side projects involving micro controllers and kernel programming. Last job was on a haskell shop, I would like to keep using functional programming at work if possible. Problem domains with lots of data analysis are great as I can use my math background.
> Perhaps it is true that worries about space leaks or surprising performance are overblown. But I think that any apology for lazy evaluation in Haskell should attempt to understand and argue against the reasons that someone like SPJ would say ‘the next Haskell will be strict’. (I’m not totally sure what the reason is; maybe it’s just that lazy evaluation is unpopular)
You are completely right. The type (b) of space leaks that are a correctness concern must be addressed. I was intending to do a second post about it.
I have a classification of space leaks that gives rise to defensive patterns to avoid the class (b). In general space leaks come in two varieties:
- Strictness space leaks: there is thunk that to be evaluated need to enter another thunk and another and another, usually growing in size. If we had evaluated in the reduction we could have collapsed the layers accordingly. The classic "foldl' vs foldl" leak is of this kind.
- Liveness space leaks: There is a reference that is kept alive because is needed to evaluate a thunk. If we force the thunk, that reference is marked dead and collected.
Type 1 of leaks are a property of functions with recursive calls or functions are that are binding expressions (such as >>=). They are local property leak. Type 2 are a global property and the more common kind. Obviously seq appropriately on a strict monad solves the issue. I will do another blogpost discussing the defensive patterns.
I am a (applied) mathematician turned software engineer. I have worked at backend services and iOS apps. I have some side projects involving micro controllers and kernel programming. Last job was on a haskell shop, I would like to keep using functional programming at work if possible. Problem domains with lots of data analysis are great as I can use my math background.
Remote: Yes
Willing to relocate: Yes
Technologies: Scala, TypeScript, Haskell, C, Python
Résumé/CV: https://drive.google.com/file/d/1gybGW79IH0FGknYaGL2Yr6nhwMK... Email: [email protected]
Mathematician (optimization) turned software engineer, 5+ of experience. I believe that with good mathematical models we can ship better code and products. I have good experiences doing front-end development but I am a better backend developer. I have a slight bias to functional programming. I pride myself on shipping products that our users have loved. If you work on a domain with good data, I would love to take a look.