HNHacker News
TopNewBestAskShowJobs

akra

174 karma · joined March 18, 2016

submissionscomments
akra··on Why F# evangelism isn't working (2015)
Would agree with this. I don't think the language choice, is as massive bet on the business as people think. I've seen much more niche and ancient langs without an ecosystem (no libraries, no SDK's to popular products, etc) build very profitable products. I would see these languages as a much greater risk.

As long as it has a base capability (libraries, maturity) and when people join they can be productive with it in a month or so then the risk is pretty low. For F# most .NET developers, even Node developers IMO will get used to F# relatively quickly. From my anecdotal experience with a number of languages its probably one of the easiest to onboard out of the FP langs balancing the FP methodology while trying to be practical/pragmatic. It has a large ecosystem via the .NET platform and supplements it with FP specific F# libraries where pragmatic to do so.

akra··on Why is inflation so sticky? It could be corporate profits
Precisely. Inflation is not even - if it were it wouldn't be nearly as much of a concern. There are winners (e.g. corporate profits) and losers (e.g. workers on fixed salaries).

Unfortunately some economic actors can protect themselves, even profit from inflation much easier than others. Inflation usually hits the poor the hardest. Given the same amount of real resources this is because other groups of society can take advantage of inflation to increase their share of the pie.

akra··on I wish GPT4 had never happened
Still a potential possibility - sadly IMO more so than the utopia vision of AI; thanks for reminding me of this. We simply become fodder for the things AI can't reasonably do in the "real world" until it can with the owners of the systems living it up. At that point the rich/political class have no need for the "rest of us", live the high life and the rest of the population is a "problem" that has to be managed by the state creating mass inequality.
akra··on I wish GPT4 had never happened
Only to a point. When you have large wants, but low capacity to meet those wants, then that is true. The law of diminishing returns however is that the utility to an individual declines as efficiency rises. It isn't a linear relationship.

The other factor to consider is that the nice-to-have wants from greater productivity in labor may just be required for me to accumulate more scarce resources especially as the population of the world grows. Opportunity cost eventually make me prioritize my investment elsewhere rather than adding scope as you say.

The industries where AI doesn't touch/win, or have real world scarcity constraints even in the face of AI is ironically where the power will be. Hence people saying to get into trades, and physical skilled jobs where we are still winning the arms race against AI for some time yet.

akra··on I wish GPT4 had never happened
For me monopolies, even natural ones, are maintained due to power structures in society. If you see most natural monopolies that are privately owned there's usually a political system that allows that to occur and a well connected powerful actor. AI has the ability to break the one power structure keeping the middle class intact - that being they still technically need people to "think on the ground" to provide the things they want. i.e. output is still a function of labor. AI breaks the need for "labor" to be a required input into the production line long term - i.e. it will no longer be a large economic factor of production.

My personal view: AI makes most of the world's population in the long run surplus to requirements for people who own capital, societal power and the planet's scarce resources. That's a form of monopoly.

akra··on I wish GPT4 had never happened
> And I think the risks from AI are overblown, is AI really more dangerous than the invention of gunpowder, electricity, and of course the nuclear bomb? I don't think so.

It might just be. Those inventions did destabilize society quite significantly. On the nuclear bomb I'm not sure we've seen how that one plays out quite yet. Mutually assured destruction kinda stalling that one. Maybe AI can be more selective as a weapon and easier to employ? In the next war we could be living the next AI sci-fi movie.

Unintended consequences are hard to predict in advance. Who would of ever thought the first professions to be at risk of software automators were going to be the software professionals themselves 10 years back? People were predicting the end of menial blue collar jobs and replacement with robots and automation. "Jobs of the future" were white collar, at least that was the narrative a decade or so ago. Now more than one comment on this forum (and I believe given human nature and the nature of power they are correct) thinking they need to change into blue collar jobs or become teachers, etc.

Sadly my personal opinion as I've gotten older is that technologists (I was one) are often the most idealistic naive of them all. The trades people I know when I talk to them laugh at ChatGPT - serves them right is the general reaction. Its that quality that often leads them to deny what an average human with power/wealth will do with AI.

akra··on I wish GPT4 had never happened
We wouldn't have the invention of ChatGPT I would imagine. The pooling of resources to create such a thing probably wouldn't of occurred, or not as soon.
akra··on I wish GPT4 had never happened
The problem is often technology becomes a barrier to entry especially when it requires scale to operate. AI is the extreme example of this kind of technology - needs large compute, and large amounts of data, and requires a actor with enough capital to create it. In effect a lot of modern technology has helped create monopolies.
akra··on I wish GPT4 had never happened
Its really a function of who is paying for the tech, who owns it and what do they want to do with it.

The only reason the middle class was born was because trained workers could pull their labor and affect upper class wealth. They had power. AI takes that power away.

akra··on OCaml 5.0 Multicore is out
Maybe so. But it benefits from the larger ecosystem that it can piggyback onto. This is often important to people selecting a language bound by constraints in their product, company, etc and can't be dismissed.

.NET/JIT/GC improvements, improvements to core API's, enterprise libraries/SDK's, etc. C#'s improvements do tend to flow into F#, if not from a language/syntax perspective from an ecosystem perspective. An upgrade of .NET version for example also benefits a F# developer greatly even if no work is done on the language at all for example. A performance improvement in say ASP.NET Core benefits many of the F# web frameworks too. A language/tool is more than just its syntax - you need to learn the libraries, package management, build tools, etc as well and be confident of their long term support/improvement. All dimensions are important.

At this stage F# does have more broader technology support and interoperability as a result of this "second class" status. Whether this matters depends on the use case, company, and engineering resources at hand. Being second class may be more feasible for a language that can ride the tail wind may be better than standing on its own two feet? Right now in my context personally I could use F# for my company's apps and not hit too many blockers, I probably couldn't use OcAML given the technologies we use day to day.

akra··on Why Domain Driven Design?
From experience I've found it easier in FP languages to get right, and have them stand a few years than standard OO without it being a maintenance headache having written a few of them. So yes - I figured the same thing.
akra··on Don’t call it a comeback: Java is still champ
I don't feel its the biggest pain to be honest, at least not in the .NET world where the Async API is so persuasive. I don't think the paradigm would suit Java - the API changes to make it ubiquitous would make it take too long to add value. People seem to code with it (the Async workflow) just fine, and it's a decent model to write some async algorithms. For example firing a few in parallel, starting a task but leaving it running and awaiting it later, etc. The advantage for me is that there is some overhead with Async dispatch - the abstraction of coroutines, green threads, etc is cheap but isn't free and maybe seeing where it could prop up isn't always a bad thing. There is value in knowing that an operation could be async, at least in my time programming and it has a cost that you may not want to pay, defer, delegate to someone else, etc especially in hot loops (e.g. IO).

As a single anecdote working in both languages in my current job in a cross platform environment when having to write Java it feels just that bit more painful, and just that bit harder to get the same performance for the class of apps I write. YMMV.

akra··on AMD passes Intel in market cap
I would say this applies to any business these days that uses technology, not just a tech business. Advertising, banking, etc. Funding models, bean counters, finance vs strategic, all go to making the business harder to deliver product quicker long term. I've been in these organisations, and it fails due to sheer bureaucracy and the numbers always needing to stack up.

The sad thing is transformation/turn around of businesses never stacks up finance wise. Its hard since the current business is a "sunk cost", and transformation is seen as a big expense with no additional value. i.e. it just puts you where you are. Its also usually requires understanding a business in full and untangling it which is expensive and usually requires significant changes and/or uplift. Most of the time they will ask - Why not just do what we've always done? Why not just use the old thing that works? etc etc.

Its the reason startup's can sometimes disrupt and take over large leaders in the field with much less capital. They have less to lose, and can just do the right thing for now. In some ways AMD had less to lose.

akra··on Ask HN: What are some cool but obscure data structures you know about?
As a case study we evaluated the performance of this along with other languages that use immutable data structures (perf testing) for a recent production app we were building. After some evaluation we had the opinion that the penalty of using immutable HAMT's on the Node/JS platform is just too high, at least in its current lib form. Immutable structures are often somewhat slower, but the relative penalty of using a HAMT on the Node/JS platform vs a straight mutable structure was much higher than other languages. Floats for numbers, conversions back and forth implicitly, pop count intrinsic missing, conversions in and out, and other such overheads make the relative penalty of an immutable HAMT vs a mutable JS map much higher compared to other languages such as .NET or Java let alone C/Rust.

Given Node is mostly single threaded as well some of the advantages (not all!) of immutability diminish on that platform making the performance penalty harder to swallow, at least for my use case.

It of course may not matter to your case, but I find the benefits of these structures come from their quicker clone/copy time in many applications, snapshot like characteristics, easy large diff's, etc. For this to matter the collection has to be of a decent size where a linear copy/equals/etc is too slow to work for the use case. At that point speed starts to matter as the costs of random lookup start to grow/drift further away from a standard mutable map and for JS we deemed the penalty too high and decided on another backend platform amenable to writing generic data structures.

akra··on .NET 6 vs .NET 5 speedup
That seems a bit misleading of a comparison IMO and only one case (JSON serialisation) when I look at their data. You are also linking to a round from two years ago which is out of date. It's also showing a lot of frameworks that are not that mature and not well used in the Java camp vs ASP.NET that is widely used, full featured, has a lot of bells and whistles and a lot of plugins available for most technologies and standards. All of which could have negatively influenced performance, even the hooks to allow them to be injected in can do so even if not enabled. The fact that a full featured web framework makes it close to the top (sometimes the top) over several rounds over many of their categories of use cases I can't discount as pretty good.

i.e. Its hard to read benchmarks without context of each framework shown, the compromises they have taken, how usable it actually is for building software vs just a benchmark, what shortcuts are done in the benchmark, how idiomatic is the code, etc.

https://www.techempower.com/benchmarks/#section=data-r20&hw=...

My personal experience having worked on both platforms for several years is that Java is easier to get to an acceptable performance, but the .NET runtime when you have to put the effort in has a higher upper bound of performance. It just has more tools in the CLR to work with than the JVM (e.g. value types, proper generics, spans, and more) so you can express something with a little more mechanical sympathy. Java is left with some decisions from legacy IMO that by default hurt its performance (i.e. lots of default boxing has hurt me before especially with generics). With .NET Core and future versions I think .NET is also taking up Java's default perf area as well. YMMV but if I'm worried about performance being a risk in my project .NET gives me more tools to optimize it IMO should that risk eventuate.

akra··on Lesser-known Postgres features
Then you are lucky. I once found an insert performance drop of sometimes 5x once a table reaches 500,000 elements or so with BTree's and Uuids in particular. Problem is: UUID's often scale well on the app side, especially with multiple writers so the app wants to use them.

Unless you are using a time sorted UUID, and you only do inserts into the table (never updates) avoid any feature that creates a BTree on those fields IMO. Given MVCC architecture of Postgres time sorted UUID's are often not enough if you do a lot of updates as these are really just inserts which again create randomness in the index. I've been in a project where to avoid a refactor (and given Postgres usage was convenient) they just decided to remove constraints and anything that creates a B-Tree index implicitly or explicitly.

It makes me wish Hash indexes could be used to create constraints. They often use less memory these days in my previous testing under new versions of Postgres, and scale a lot better despite less engineering effort in them. In other databases where updates happen in-place so as not to change order of rows (not Postgres MVCC) a BRIN like index on a time ordered UUID would be often fantastic for memory usage. ZHeap seems to have died.

Sadly this is something people should be aware of in advance. Otherwise it will probably bite you later when you have large write volumes, and therefore are most unable to enact changes to the DB when performance drastically goes down (e.g. large customer traffic). This is amplified because writes don't scale in Postgres/most SQL databases.

akra··on New language features since Java 8 to 17
Its not universal to all of .NET though.

F# does support this (e.g. Task<unit>) because in F# every function has only one input and one output. Therefore it needs a unit/void type at the lang level at least. This simplification surprisingly results in more power and less code compared to C#. Its part of the base design of the language, and an example of something that is hard to change afterwards in future versions.

In F# overloads for different amounts of type args to a function are not common, unlike C# with different types for each Func<T1, T2, T3, ... TResult> or Java with both Supplier and Function types and needing a custom function type for more args last time I checked. A use case that has come up for me would be to dispatch on variadic template args (e.g. loggers) in a typesafe way without reflection penalty, or looking at some of the libraries using overloads that could be reduced (especially in conjunction with inline for the value type overloads I suspect such as found in LINQ). When I see libraries with overloads for parameters like 'Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,TResult>' I think of this. Wherever you see multiple overloads in C#/Java just for the sake of multiple generic arguments; that can often be simplified if required/worth it.

akra··on What I wish I knew when learning F#
Yeah I think 'dotnet fsi {fileName}' with a script file works. Also Ionide with VS Code using Alt+Enter (similar to other language VS Code repl's) inside a *.fsx script file to run the highlighted code in a F# REPL. F# Interactive has doco online as well that isn't that long but covers most things (single commands, script files, loading packages, etc).
akra··on What I wish I knew when learning F#
Sometimes that's true but I've found as soon as I need packages things get complex. I don't find F# that hard scripting wise; at times found it easier than some other languages especially when I need to import libraries into my script. Instead of needing to install a system wide pip package, set up a project with Maven/Gradle, etc around the script, etc. With F# and the like you just do something like:

#r "nuget: FSharp.Data"

And it pulls that third party package into your script context. Its kind of empowering when I can just copy and paste script text to my colleague (e.g. email/slack) and all they need to do is copy/paste the text into a single text file and it just works third party packages included with a vanilla .NET 5+ installation. Just run 'dotnet fsi scriptFile.fsx`. Auto-complete picks up all the new types as well.

Documentation seems pretty straightforward to me: https://docs.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-...

akra··on Currying in JavaScript
Not quite. In curried languages functions often only take in ONE argument in and return ONE value out. That simplification means the language can only accept the latter form (e.g. foo(a)(b)). Surprisingly this makes the language more powerful not less by unifying all functions to one shape.

For example this allows you to write methods that only take 1 input and 1 output type arg and handle all function cases with any amount of arguments. e.g. in Java/C# you typically have lots of types/anonymous class shapes to define different function shapes to represent lambdas/functions.

e.g. C# delegate syntax (Java has a more verbose way to do this last time I checked)

delegate T Action<T>(); delegate T Func<T>(); delegate R Func<T, R>(T firstArg); delegate R Func<T1, T2, R>(T1 firstArg, T2 secondArg);

Java has things like Consumer<>, Supplier<>, Function<> etc. If you want more than a https://docs.oracle.com/javase/8/docs/api/java/util/function... you typically have to define your own template that's not standard.

However in curried languages all use cases typically are handled by one form and the compiler does the mapping for you (e.g Haskell, F#, etc).

type Func<T, R> = T -> R

The compiler translates a method like foo(a, b) to foo(a)(b) and has certain compile tricks to avoid intermediate allocations if you're specifying all the args at once.

In practice it means writing a LOT less overloads to deal with all the different argument length cases defined and a lot less "Function" types to consider. Instead of an overload in Java for example with Function, BiFunction, etc or C# with Func<>, Func<_, _>, etc you just write the one or two and chain it.

akra··on TC39 Pipeline Operator – Hack vs. F#
There is pros/cons to both approaches. The Pipe operator in F# works in conjunction with the HM type inference in the language and static functions often assisting the type checker. i.e. features that work together in a language vs tacked on. F# idiomatic code avoids a lot of virtual dispatch seen in Java/C#, etc as compile time polymorphism is typically how re-use occurs vs objects. I find F# favors compile time abstractions a little more than Scala historically although I note that could be changing.

For most of these proposals it is just syntactic sugar around invoking the function with a placeholder. The pipe in F# is slightly different in that most of the time it has no intermediate lambdas and is compiled in a more performant form. The downside is that unless you allocate that lambda yourself it has to be the last arg. On the plus side like most things in F# it is concise but shows all behavior explicitly - its usually a warning sign if you have to do that and helps reason about performance. Sometimes its a sign that the original function isn't written right or some other inline wrapper could be used for other usages of the function. You can inline a template to rearrange the arg's (inline) to avoid the lambda allocation as well.

This allows some level of re-use and performance benefits avoiding virtual table dispatch and a lambda allocation for many common methods (e.g. map, fold, iter, etc)

akra··on TC39 Pipeline Operator – Hack vs. F#
> Chaining methods on classes

But defining these is typically left to library authors in many languages. Writing your own Fluent/chaining interface isn't usually worth the effort. Where in these languages because any function is "chainable" and gets it for free a lot of programming ends up being chained pipelines. Anything where there is a logical workflow (a lot of programming) ends up being nice to read when expressed with pipes (i.e. do this, then this, then that, and finally return this). The pipe operator goes hand in hand with currying as well since you can complete some of the arguments before wiring the partial completed function into a generic workflow; a pattern that typically isn't be done with Fluent/Chaining methods on classes.

akra··on Surveilance bill rushed through Australian parliament in 24 hours
Depends what state you are in from what I've seen in news reports. States that failed on COVID have lost their freedoms (quarantine/lockdown) since the hospital system is under strain. If you are in 5 of the 7 states (not NSW/ACT, VIC you probably have the most freedoms out of many developed countries right now.

Its a tale of two opposing extremes.

akra··on Software Dev Can't Be Automated – It’s a Creative Process with an Unknown Goal
I think this equally applies to languages that are more geared to REPL and/or scripting development (e.g. script languages and/or functional languages). Not just Clojure.

OO requires a bit of boilerplate and structure up front IMO, at least the Java/C++ variety. IMO the structure typically has to be re-invented each project as well. i.e. what factories, interfaces, parts will I need?

akra··on AMD vs. Intel CPU Market Share
Archlinux. Didn't really need to consider drivers; things just worked out of the box mostly with exception of the GPU where I've installed the AMD driver via pacman (a one liner).
akra··on AMD vs. Intel CPU Market Share
Using an AMD desktop now (Zen 2), no issues with Linux at all. Uses all the cores, and detects everything just fine.
akra··on .NET Open Source: What Happens When the Free Lunch Ends?
As an example the other day I was writing low level protocol code in F# (but could do the same in C#), allocating a decent byte array on the stack (stackalloc), putting value types in it, bit-shifting and putting those numbers in place in the same byte array without a single heap allocation nor a single unsafe block of code or needing other techniques like byte array pooling. In previous days the only choice often was jumping into C/C++ and writing extern functions that usually had an associated penalty especially in hot loops where we want to employ this style of coding. Made me realize how far the .NET Core ecosystem has come in the last few years. When having to go back to Java I do see the performance penalties that I didn't see many years ago.

And yes this code is all going to be hosted in containerized Linux infrastructure. Our tests showed much better single and multi-threaded performance for our cases than many other popular frameworks across many languages we evaluated. YMMV but IMO the ecosystem has made up a lot of ground in a small space of time.

akra··on Immudb 1.0 – open-source, immutable database with SQL and verified timetravel
I would imagine there are a few differences. Events are the primary entity, and the current state is simply a projection of that not the other way around. Those events may come from other systems and are often defined in business terms, not SQL terms. For example an event may also constitute a business update which can update one or many tables. Think of a transaction event updating a balance for two accounts.

TL;DR My thinking it allows you to capture more the intent of that event. Although I'm not sure you need an immutable database to do this from scratch - I've seen this in schema designs in the past?

akra··on How Intuitive Are Macs Really?
Actually some companies do. You want Linux since the software you are writing typically leverages a Linux environment, but the company doesn't want to support Linux so gives you a Mac machine instead. Its a poor substitute for the real thing IMO on a number of fronts at least for me. While it still works some of the time I would prefer a different environment and enjoy things like better Docker performance, avoid compile time differences between ARM and x64, odd differences in Terminal command behavior, etc, etc.
akra··on How Intuitive Are Macs Really?
"I've probably already typed Cmd-N or Cmd-O, depending."

This is, particularly for a novice or intermediate user IMO quite intimidating. It means there is some learnt behavior + keyboard command required to "see anything" and work with the program. If I'm using my trackpad/mouse trying to work out after I start a program why I can't see anything like I've seen new Mac users do for some time it isn't great. Because there is no window its easy to click anywhere else in my search for my "missing program" and immediately lose the "menu bar" that allows you to (Cmd-N) or discover the ability to do that. It's almost like the app never booted up.

Sure you can learn behavior and work around it as I and you have had to do, but if the menu bar behavior changes per window focus anyway I don't see the difference than Windows with menu bar on the window other than "its the Mac way".

← PreviousPage 2 of 5Next →