322 karma · joined October 13, 2019
Here’s the livestream: https://www.youtube.com/live/c0pw1iVs_Q0?is=hwm2xa4cZOcqF5tW
Well post the individual talks in the following days!
I think we are in a similar situation with code generation now, then only difference in my mind is that LLMs come with a massive platform risk. Who's to say that one day anthropic decides my company is too much of a competitor to use their tool (like they've already done with openai) or what if they decide that instead of pulling their product from my use they just make it generate worse code, or even insert malicious payloads. A dependence on these tools is wildly more risky than dependency on a word processor or a spreadsheet program. It reminds me of the arguments around net neutrality and I cannot fathom how people building on top of, and with, these tools do not see the mountain of risks around them.
Here's how I think of it: If I were a painter, I would paint, explore and experiment in my free time because its what I want to do. Maybe, as a painter, my vision is to improve the state of the art of some kind of dye or brush or canvas and that is my vision. But! That does not mean that I cannot be commissioned to work on a mural or put on a retainer for a museum or something else. The only difference is that in the latter you are being explicitly payed by a patron to produce something they want. And furthermore I need that work, I work for myself but still need projects to bring in money to do the work I care about.
I view my software dev as the same thing. I have a vision of where I want to be, what I want to do, and how I want to contribute to advance the state of the art of the things I care about. I do not care, and am unconcerned about the corporate needs of the thing I care about, its for me and for people like me. My $JOB is just one part of that larger goal and the path I walk towards that goal. Its an important part, sure, and I show up and give a good faith effort and my expert opinion, but its not the part that enriches me as much as my personal stuff. The distinction is that the $JOB is not separate, its a necessary and important part of my plan to execute on my vision.
Once you have vision I think you'll find its much easier to find similar people who want to work on the same things you want to work on. And I think you'll find it much easier to tolerate capitalist minutiae because you will reduce the things you need from $JOB.
I see how the use of AI is useful, but I feel that the practitioners of AI-as-coding-agent are running away from the real work. How can you tell me about the system you say you have created if you don't have the patience to make it or think about it deeply in the first place?
For example, I would create a game fight scenario where the player has infinite health and the enemy just attacks super fast at some settable rate. That way you could monitor whats happening in extreme abnormal conditions with the hypothesis that if the game works in extreme conditions then it will work in normal conditions.
Another example. If you have random encounters like in old school JRPGs then I would create a scenario where a fight happens per step of the player, the fight loads, then the enemy immediately dies, rinse wash and repeat. That should allow you to asses how the game performs after 100s of fights quickly.
The idea here is to create tests that improve your signal to noise ratio. So you create a scenario that will create a large signal so that then you can more easily diagnose the performance issues.
fibonacci :: (MonadLogger m, MonadState (Int, Int, Int) m) => m Int
fibonacci ...
and now of course all callers must support MonadLogger. But instead of using the MonadLogger (or any mtl constraint directly) you should just be constructing an abstraction boundary with a type class synonym: class (MonadLogger m, MonadState s m) => MyMonads s m
and now you change fibonacci: fibonacci :: MyMonads (Int, Int, Int) m => m Int
fibonacci ...
And now if you need to add a monad or add Eq or whatever you just have to change your type class synonym rather than every function. Its not a problem with the language its just programing with modularity in mind, even in the type system.So I would argue that the real message of that chapter is demonstrating, step-by-step the methods used to find the memory leaks: info-table profiling and biographical/retainer profiling and ticky-ticky profiling.
But that doesn't mean that laziness doesn't come up! For example, its impossible to demonstrate using (or defining) unboxed or unlifted types without discussing laziness. The same goes for using GHC.Exts and explaining the difference between Data.Map and Data.Map.Strict.
My goal is to have a handbook that consolidates and demystifies optimizing GHC Haskell because I think this resource is sorely missing in the Haskell community. So that includes reading and understanding Core, Stg, and Cmm as well as understanding the tools that already exist for GHC Haskell but are under documented in addition to the real advanced features, like altering the RunTimeRep your data types to control their behavior at runtime. Needless to say there is a lot to do :)
Work has been steady the master project plan is tracked in this ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/17957
Almost all the recent work has been performed by Dominik Peteler (@mmhat) during Google summer of code, which John supervised. We've primarily been focused on landing !8341[0] which makes huge strides in Core w.r.t. modularity (see https://gitlab.haskell.org/ghc/ghc/-/issues/21872), but are on hold until schedules agree and some vacations end.
So the modularity project is far from dead. In fact Sylvain and I are planning on returning to it after we upstream the new Javascript backend (slated for 9.6, see MR!9133[1], tracking ticket[2]) hopefully this week.
PS: That patch is actually a good example of a gnarly lung transplant for GHC's Core IR (and done by a new contributor!).
[0]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8341
[1]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9133
I'm probably a lost cause now because I think I'm going to convert my entire raspberry pi cluster to NixOS from ubuntu.
Trackpad seems good to me but my setup is not trackpad heavy. In fact I have a hotkey binding in xmonad that disables the track pad because everything I do is keyboard based including my browser. So I find I rarely need to use the mouse and it just gets in my way.
Battery depends on usage, with nothing (nothing is emacs daemon, wifi on, bluetooth on, xmonad and syncthing running, I don't use a desktop environment) running my battery reports a discharge rate of 5-6W, with normal usage (firefox and chrome open, slack and spotify open) the battery discharge is ~9-10W which is easily 6 hours, of course when I'm compiling GHC with all cores firing away this shoots up to ~30W and battery tanks to 1-2 hours but I can't really blame the machine for that :)
I've got to say, as long as these things are being produced I'll never go back. They are just too good and I cannot recommend them highly enough. One of the things that didn't occur to me before I bought it was that _because_ of the modular design I can switch the side the power port is on. That may not seem like much but it was a revelation the first time I sat on the couch and thought "huh I really wish this was over on that side....wait a minute!".
I've also had absolutely no problems with NixOS on my machine, even my apple earbuds easily connect via bluetooth, something that I never quite got working on my macbook.
10/10 This is damn close to my dream laptop and I'm excited a new version is on the way.
But I switch to Doom emacs literally two weeks ago and I'm never going back. I find doom to be much faster not just startup time but in general responsiveness (one major exception: hitting SPC and waiting for key binding tips to show seems to be much slower in doom than spacemacs). Other than that I found doom to be much easier to configure and much more configurable.
The major selling point for me was that in doom emacs there is much much less ceremony in wrapping a new package in a module, and more importantly it is _easier_ to reuse documentation for those packages because most packages provide configuration examples using `use-package` anyway. My only hangup was less documentation around writing custom modules which took me about a day to figure out (I would advise to just read some of the source code or mimic a module that doom ships with).
YMMV, but if you feel like you've attained a certain level of emacs maturity, I would 100% recommend trying it out. Be prepared that some modules, like the haskell module, don't ship with a lot of keybindings so you'll have to set those up yourself.
Strictly speaking the expression problem is only defined for _static_ type systems because its concerned with _static_ type safety and extensions without recompilation.