HNHacker News
TopNewBestAskShowJobs

jasim

8,134 karma · joined May 1, 2010

https://protoship.io

https://twitter.com/jasim_ab

jasim.ab@gmail.com

submissionscomments
jasim··on Restack: Full-Stack ReasonML
Here is a non-trivial production web application (a learning management system) that runs Rails on the back-end, GraphQL for network communication, and Reason on the front-end: https://github.com/svdotCO/pupilfirst
jasim··on Restack: Full-Stack ReasonML
The ReasonML ecosystem is evolving at a fast pace and finding adoption in the most unlikely of places (Most recently a team inside SAP for some of their front-end).

However, one of the better things about Reason for me is that it is based on OCaml, which has been a rock-solid language for more than two decades. Its pace of evolution is quite measured - for example the algebraic effects work that has been happening is based on a formal academic foundation, and the implementation is often lead by researchers who wrote the actual papers.

The biggest issue I can imagine when a company adopts Reason is availability of bindings to Javascript libraries. In practice this has not been much an issue for me - once you get grips with the way bindings are done in BuckleScript, creating a binding is just another thing to do.

The other issue is significant upfront learning cost for the Typed functional paradigm. But it is the kind of fundamental learning that pays dividend for a long time, quite unlike learning libraries or frameworks that simply keep coming and going.

I find that Reason and Elm does solve for this constant library/framework trivia-treadmill of the Javascript ecosystem admirably, helping teams achieve enough technical expertise so they can effectively create most of the building blocks they need by themselves.

jasim··on 3Blue1Brown and the Beauty of Mathematics [video]
"Is math discovered or invented?" is a question that underlies a lot of math philosophy writings I've read (of the popular science variety) and so I could immediately understand where Lex was going with it. It is a simple question which can elicit as much depth one is willing to dive into.

Similarly I thought all of Lex's questions came from deep understanding of what he was asking, and he would've known clearly what Sanderson would've replied (minus his personal insights) and what other competing answers are out there.

I love Lex Friedman's interviews - he simply asks a small but fertile question and then lets the guest talk.

jasim··on Brad Cox: when OOP was about “Software-ICs” and micro-transactions
Objects do have state, but they can be either mutable or immutable. The link in my original comment describes an immutable stack (written in OCaml, but is fairly readable) where both push and pop returns a new stack object. The original object is never changed. In a mutable stack, push would return void (or unit in OCaml), which signifies a side-effect. pop would return the element, and the object changes in-place.
jasim··on Brad Cox: when OOP was about “Software-ICs” and micro-transactions
Two interesting ideas that helped me get insight into OO:

1) An object is a poor man's closure; and a closure is a poor man's object.

2) Most object-oriented programming is done with mutable state, which muddles what OO is. You don't really need state to have objects.

In a closure, the lexical scope is preserved, and the functions defined in it can access it any time. This is very similar to what an object does: https://stackoverflow.com/a/2498010

When objects are immutable, one gets to truly appreciate the elegance of grouping both data and their functions together: https://dev.realworldocaml.org/objects.html#scrollNav-3

jasim··on Seven deadly sins of talking about “types” (2014)
F# has "Units of Measure" that does this. https://docs.microsoft.com/en-us/dotnet/fsharp/language-refe...
jasim··on Ask HN: How to improve code quality while maintaining decent velocity?
* Learn to think about types first, and the algorithms as a natural consequence of the structure of your data. Richard Feldman: https://www.youtube.com/watch?v=IcgmSRJHu_8,

* Use a statically typed language that allows fast refactoring. Ideally a typed functional language like Elm, Reason, OCaml, or Haskell.

I recently shipped a complex Javascript project (without types) and it is one of the few instances of my decade-old professional career where I had that level of confidence in the robustness of a piece of code I wrote. It remained sturdy in production even in the presence of unforeseen conditions. This was thanks to the habits I picked up from typed FP: parsing and validating all data at the boundaries of the system, better design by modelling data to make inconsistent states impossible, and automatically handling all edge-cases at all times.

So even if you don't actively use such a language in your workplace, there really is a payoff to learning it in making you a better programmer overall.

jasim··on In the 17th Century, Leibniz Dreamed of a Machine That Could Calculate Ideas
Leibniz: 'What a watch is to time, this engine is to thought.'

Daniel Waterhouse: 'Sir! You show me a few gears that add and multiply numbers – well enough. But this is not the same as thought !'

'What is a number, Mr. Waterhouse?'

Daniel groaned. 'How can you ask such questions?'

'How can you not ask them, sir? You are a philosopher, are you not?'

'A Natural Philosopher.'

'Then you must agree that in the modern world, mathematicks is at the heart of Natural Philosophy – it is like the mysterious essence in the core of the snowflake. When I was fifteen years old, Mr. Waterhouse, I was wandering in the Rosenthal – which is a garden on the edge of Leipzig – when I decided that in order to be a Natural Philosopher I would have to put aside the old doctrine of substantial forms and instead rely upon Mechanism to explain the world. This led me inevitably to mathematicks.'

'When I was fifteen, I was handing out Phanatiqual libels just down the street from here, and dodging the Watch – but in time, Doctor, as Newton and I studied Descartes at Cambridge, I came to share your view concerning the supreme position of mathematics.'

'Then I repeat my question: What is a number? And what is it to multiply two numbers?'

'Whatever it is, Doctor, it is different from thinking .'

'Bacon said, ‘Whatever has sufficient differences, perceptible by the sense, is in nature competent to express cogitations.' You cannot deny that numbers are in that sense competent – '

'To express cogitation, yes! But to express cogitations is not to perform them, or else quills and printing-presses would write poetry by themselves.'

'Can your mind manipulate this spoon directly?' Leibniz said, holding up a silver spoon, and then setting it down on the table between them.

'Not without my hands.'

'So, when you think about the spoon, is your mind manipulating the spoon?'

'No. The spoon is unaffected, no matter what I think about it.'

'Because our minds cannot manipulate physical objects – cup, saucer, spoon – instead they manipulate symbols of them, which are stored in the mind.'

'I will accept that.'

'Now, you yourself helped Lord Chester devise the Philosophical Language, whose chief virtue is that it assigns all things in the world positions in certain tables – positions that can be encoded by numbers.'

'Again, I agree that numbers can express cogitations, through a sort of encryption. But performing cogitations is another matter entirely!'

'Why? We add, subtract, and multiply numbers.'

'Suppose the number three represents a chicken, and the number twelve the Rings of Saturn – what then is three times twelve?'

'Well, you can't just do it at random, ' Leibniz said, 'any more than Euclid could draw lines and circles at random, and come up with theorems. There has to be a formal system of rules, according to which the numbers are combined.'

'And you propose building a machine to do this?'

'Pourquoi non? With the aid of a machine, truth can be grasped as if pictured on paper.'

-- Quicksilver, Baroque Cycle (#1), Neal Stephenson

jasim··on Show HN: Siproc – A primitive SIP client that spawns processes for each call
What is the git web server you're using? The UI is very clean and the underlying markup and CSS is also quite minimal.
jasim··on Soundex – a phonetic algorithm for indexing names by sound
Clipper had SOUNDEX function, which was used to search in flat-file databases for descriptive names. SEEK SOUNDEX("Smith") and SEEK SOUNDEX("Smythe") would return the same result. https://www.itlnet.net/programming/program/Reference/c53g01c...

But Harbour, an open-source implementation of Clipper superseded it with Metaphone - https://harbour.github.io/doc/hbnf.html#ft_metaph

jasim··on Books: an immutable double-entry accounting database service
Ask the same programmer to write an invoicing & payments system, then coupon creation and track its claims, then something where users can recharge their phone, and their usage is tracked and balance is computed -- and each one of them will be a set of ad-hoc tables and custom code.

But most transactional systems where things move from one entity to another and has the notion of "balance value" is best represented by the double-entry system.

When a customer purchases pre-paid balance, the phone company can record it as a "credit", and every call they make becomes a "debit". This is an immutable log - one of the earliest application of immutable data structures in human history.

In this post authors used positive and negative values to represent debit and credit - we could call it yin and yang for all it mattered. The core principle is just that every transaction has a source and destination and the ledger is an append-only table.

jasim··on Gridgarden: A cool game to learn CSS Grid
Imagine you take a piece of paper, draw 4 vertical and horizontal lines dividing the page into 16 cells. Now when you place an element in any of these cells with width: 100%, they'll take exactly the width of the grid cell. It can't grow beyond that.

You have a lot of flexibility in choosing the width and height of each cell, but they are rigid.

In case of Flexbox, we don't specify any fixed lines to which the elements will size. Instead, we say general rules saying elements can grow to as much size is available, or stay at the beginning of the row etc. The layout is determined to a large extend by the elements we place rather than on a fixed set of gridlines.

jasim··on Functor, Applicative, and Monad
I understand your point of view and I also don't think my understanding of Typed FP would be complete without sufficient immersion in Haskell. But even with the learning materials, it is too steep a climb for beginner programmers for whom the love of the subject is secondary to their day jobs and regular life.

For people from dynamically typed or static OO background, being able to write functional code with records and sum types alone is a huge quality of life improvement. They should be able to get there with the least amount of effort. Haskell however demands far too much understanding and effort before it can be confidently used in a commercial setting. That excludes mainstream programmers who could otherwise most benefit from the paradigm.

jasim··on Functor, Applicative, and Monad
OCaml (Reason) was my entry point into Typed FP (after a few failed attempts at learning Haskell). The best thing about OCaml is that it allows side-effects, so one can go a long way without having to touch advanced FP.

It is only recently that I've started getting comfortable with concepts cogently explained in this post, so to me it is quite valuable.

As an aside, I think OCaml/Reason/Elm should become the de-facto Typed FP entrypoint for programmers instead of Haskell. That'll help drive more adoption for the paradigm because the ecosystem is a lot more approachable and one wouldn't feel overwhelmed to even begin.

jasim··on A nice app on Elm street
:)
jasim··on A nice app on Elm street
Sometimes I wonder whether Alan Perlis would mock at us for being Bible salesmen for Typed FP languages.. yet it is such a quality-of-life upgrade and a thinking tool that it feels justified to shout from the rooftops :)
jasim··on A nice app on Elm street
Yes I was thinking of a couple of things, but most importantly the existence of null in the language. So functions either receive exactly the type they were looking for (which is better than dynamically typed), or a null (which never happens in a Typed FP language).

In OCaml, (List.hd []) throws an exception, which is not a desirably behaviour, so we mostly use a safer version of List.hd which would return an option type. This could be either "None" or "Some(value)". To operate on option types, we have to pattern match and handle both cases where the value could be either None or Some)

Exhaustive pattern matching is useful here, so is the very notion of variants. Without variants (or sum type / union type) we tend to leave domain concepts implicit in the codebase. While we can simulate variants with classes, it is too unwieldy to be used except for core domain concepts.

jasim··on A nice app on Elm street
Neither Elm, nor any language in the Typed FP family, can do that. What it can do is to prevent us from making clerical mistakes. That's the surprising thing I learned programming in Typed FP: we very rarely make logical mistakes. Our programs are all broken, make no mistake, but they are broken not because we accidentally swapped a conditional (logical mistake), but rather because we passed in data of the wrong shape (clerical mistake).

A common clerical mistake which Elm, Reason etc. prevents, is when we grab something from a list and pass it to another function. What if in a rare case it is possible that the element doesn't exist? A function deeper in the stack might crash, or if defensively built, substitute it with an empty value. Both could be wrong.

By providing more information about our data and our functions to the compiler, the compiler can ensure our code always follow those constraints. These constraints are often in our head when using dynamically typed languages, or even statically typed OO languages. Typed FP helps us make them explicit in code so the compiler can track it instead of we tiring ourselves mentally and making a mess of it.

jasim··on Wasps: If you can't love them, at least admire them
The Patrician took a sip of his beer. ‘I have told this to few people, gentlemen, and I suspect never will again, but one day when I was a young boy on holiday in Uberwald I was walking along the bank of a stream when I saw a mother otter with her cubs. A very endearing sight, I’m sure you will agree, and even as I watched, the mother otter dived into the water and came up with a plump salmon, which she subdued and dragged on to a half-submerged log. As she ate it, while of course it was still alive, the body split and I remember to this day the sweet pinkness of its roes as they spilled out, much to the delight of the baby otters who scrambled over themselves to feed on the delicacy. One of nature’s wonders, gentlemen: mother and children dining upon mother and children. And that’s when I first learned about evil. It is built in to the very nature of the universe. Every world spins in pain. If there is any kind of supreme being, I told myself, it is up to all of us to become his moral superior.’

-- Unseen Academicals, Terry Pratchett

jasim··on The history and legacy of jQuery
That might be false economy. Most images in a page would come above 30kb. I've seen 3rd party widgets for chat and support sometimes bundle their own copy of the React framework, not to mention huge chunks of CSS, most of which are unused.
jasim··on What’s it like to live on less than $2 a day?
Yet these statistics don't matter to individuals for whom life is mostly suffering. We're together in our happiness, but alone in our grief. The Gates note here recounts such stories, and even they haven't captured the deep anguish and helplessness that consumes individuals when they have no money to eat (and worse, to feed their children), and when they can't treat family from curable ailments.

Often people seem to use ideas in Factfulness (Rosling) to assuage the guilt of living well and free when there is suffering all around. This is fine, but this also seem to give ammunition to others who argue that people's fates are in their hands alone, minimum wages should be abolished, and being a rickshaw driver is fine - because they need jobs, and it is as good a job as any for people "like them". The reasoning from "things are improving" to "society don't owe individuals succor" seem to be illogical, but reoccuring nonetheless.

jasim··on TypeScript vs. ReasonML
This might shed some light: https://www.harigopal.in/talks/2018/jsfoo
jasim··on TypeScript vs. ReasonML
My recommendation for using Reason in production is to go for it -- but only if someone in the team has previously shipped production software in a typed functional programming language. If not, use it in a non-critical project, have a pair of programmers build up expertise over around six months of full-time work, and then make the jump for the entire team.

Regarding bindings -- which external libraries were you using? Component libraries written for React could be a fair amount of work to write bindings for, but I anyway prefer hand-rolling components with Tailwind, so that hasn't been a problem personally.

Bindings were indeed difficult when I started out - Javascript can invoke functions in a myriad ways: new xyz(), object.key, object.key(), module defaults, Math.abs etc. We have to map them to OCaml's semantics (easy), and figure out the BuckleScript macros for them (easy with practice). I recently wrote a bunch of bindings for Adobe XD, and it was surprisingly fun.

jasim··on Starbucks, monetary superpower
More generally, reality just gets more nuanced as things go broader or deeper in scope. Toy projects are clean, uncluttered; production code needs error handling, logging, monitoring, scaling, and much more.
jasim··on Lisp is not based on the Lambda Calculus
If I understood you right, Lisp was not directly inspired by lambda calculus, but from McCarthy's own research into recursive functions where he found that the three primary functions can cover the whole of computation.

What I'm extrapolating from this is that McCarthy's ideas are similar in implication to Lambda Calculus where you can define computation with just function abstraction and application, and use Peano numbers to represent data. Both approaches end up creating a purely functional way to write programs.

Would that be correct? I also wonder whether there is anything we can take away from this knowledge that is applicable to programming or how we look at it?

jasim··on Show HN: Tailwind.run – An Online Playground for Tailwind CSS
Don't use `text-gray` if you're building an app that needs to be themed like that. Instead use `text-secondary` or a similar name that you'd otherwise use in a themeable system. Tailwind lets you define _every_ single design token in the system and comes with zero opinions there.

If you want to change density of the design, you can change the spacings centrally in the configuration itself. But if you need a non-proportional change, then it isn't any different than BEM+SASS environment where you'd have to go into every CSS class and make the change. I think it is even better than BEM here because you only need to change classnames in HTML, which is co-located with the style, and it doesn't cause cascading changes due to specificity etc.

To me the opinions you hold seem to come from not having tried it in good faith, which was how I used to judge functional CSS as well. If the current CSS style you use serves you well, that's fine you don't have to explore. But if you've wondered whether there is something wrong with the way we do CSS today, then Tailwind could be an eye-opener.

jasim··on Largest Contentful Paint
Front-end often has longer data transformation pipelines than back-end, and that leads to the complexity you mention.

If you treat it as a programming problem, you can write better front-end code by shoring up on your ability to compose, glue, and modularize code. You also need a way to represent front-ends as a data structure rather than a sequence of imperative actions. Data is easier to think about - imagine if instead of HTML you had to write imperative code to paint everything on the screen - that kind of code can get tangled up easily and make it difficult to understand or modularize the code.

In this vein, using a library that lets you think of the front-end as data ('declarative') rather than imperative DOM mutation (with jQuery etc.) is an important thinking tool.

A way to short-circuit the amount of learning associated with this is to pick-up tools that have already reified this knowledge, so that by learning the tool you pick up the many mental models they embody. I suggest either Reason (with ReasonReact) or Elm as great starting point. Pursue their homepages, toss a coin, pick the one that appeals to you on first blush.

Both these languages are typed functional languages. Types here are tools of thought - especially the ability to represent data as One of Many (sum types) - will forever add a dimension to the way you model data. Functional programming is a toolkit of methods that let you compose and glue code together, and while it wouldn't appear that they attack the problems you're facing head on (should I add yet another conditional here, or should I extract another function that looks almost the same vs DRY etc.), those are exactly the problems you'll be able to confidently answer after you've practiced in this paradigm for a while.

jasim··on Show HN: Tailwind.run – An Online Playground for Tailwind CSS
There is no good way to solve it using Tailwind classes alone. You could parse the markup first and add Tailwind classes before rendering them, but that is too much pain for very little reward.

The best trade-off I've found is to give a unique CSS classname for the container which has user-generated content, and then style it using nested selectors. Here you can use Tailwind's @apply so you're still able to rely on Tailwind's design system.

jasim··on Show HN: Tailwind.run – An Online Playground for Tailwind CSS
Tailwind makes it very easy to change theme by changing just a single configuration file: https://tailwindcss.com/#designed-to-be-customized

It is very liberating to use Tailwind instead of creating unique CSS classes for every div in a page. The code is much more maintainable - in a single stroke Tailwind gets rid of selector specificity issues, design inconsistency, and naming woes.

From a programming perspective, the conventional style of "semantic" CSS classes creates deep and fragile coupling between markup and CSS. It goes against everything good code is supposed to be - when you change the structure of the HTML you're forced to change the CSS, and if you truly use the power of CSS selectors, then modifying CSS becomes a difficult enterprise: one change can create multiple unrelated changes at a distance.

Tailwind solves all this, with just two downsides: until you spend a few hours mucking with it, the markup look will look unwieldy, and you have to be ready to really think about semantic CSS and "separation of concerns" dogma we've taken for granted for so long.

jasim··on The Lonely Work of Moderating Hacker News
The political discussions that make their way into HN are very US-centric and that excludes me and countless others who actively participate here. A lot of such discussions are not real enough to me - they are problems of a much more privileged world. If we were to have truly political discussions, we'll need to include all the other countries of the world, which none of us would want. There are other places where political conversations are dime a dozen, but no other place like HN for technology, and things that "gratify one's intellectual curiosity".
← PreviousPage 4 of 17Next →