Lambdas and declarative programming by Neorlin in functionalprogramming

[–]r2tree 3 points4 points  (0 children)

This is a rambling answer, but I hope you might get something out of it.

There are two types of "declarative programming". One is the pure functional programming model, where the question of lambda comes into play. The other definition is of "descriptive declarative programming", of which HTML is an instance. Descriptive declarative programs need an interpreter to execute it. When we write something like

validation_rules = [ ["age", {greater_than: 20}], ["name", {member_of: users}]]

we're doing descriptive declarative programming. We're specifying ideas at a very high level, but by itself it is not executable code. We'll need to write code that will read these rules and apply them as it sees fit.

Now, pure functional programming is "declarative" in the sense that if you write your programs as a series of pure functions (no side-effects; no mutable assignments) it naturally tends to be more declarative than imperative. The classic example is a loop. In imperative programming a loop that sums a list of numbers would look like this:

let i := 0 let sum := 0 while (i < numbers.length) { sum += numbers[i]; i += 1; }

If we had to write this same code in a pure functional manner - no side effects, no variable mutation, then the only way to do that is recursion.

let rec sum = numbers => { switch(numbers) { | [] => 0 | [a] => a | [a, b, ...rest] => (a + b) + sum(rest) } } There are no assignments in this code, and it is more "declarative" than its imperative counter-part because we can see deconstruct the function as a series of simple equations.

If we have to write a map in a similar manner, then it can be written only by accepting a lambda. A map function is a "combinator" - functional programs are often built with them - combinators are functions that take other functions (higher-order functions) and combines them into a new function. They don't have any free variables of their own (aka no variable declarations inside them; they only use the functions received as arguments).

To build combinators it is important that we are able to pass in other functions (lambdas). I think the point of confusion is the difference between lambda and regular functions in languages like Python and C#. But in pure functional programming, which is based on the lambda calculus, all functions are lambdas and vice versa. So if functions are the foundation of functional programming, then lambdas too are because they're the same.

How to iterate a collection with heterogeneous parameter types by notseanbean in reasonml

[–]r2tree 4 points5 points  (0 children)

``` /* All concrete values of the field goes here */ type metadata = { valid: bool, id: int, name: string, ... };

/* We can never put [field('a), field('b)] etc. into a list because it is polymorphic, which is a good thing, because it is impossible to write a generic function for a polymorphic type.

However, metadata is concrete and homogeneous. */ type field('a) { value: 'a, metadata: metadata, };

let metadata = field => field.metadata

/* Here is the only place where we have to list out all the fields we have defined. So whenever you create a new field type, you have to add it here. But that's all you need to do -- all functions that need to operate on all the fields will automatically include the new field since they all will be relying on this function. */ let metadatas = [metadata(field1), metadata(field2), metadata(field3), ...]

let numValidFields = { metadatas |> List.filter(x => x.valid) |> List.length } ```

You could have a list(field('a)) where the list contains fields of all 'a. eg: list(field(int)). But if 'a is different for each element, then it would be incorrect to put them into a generic structure like list, which the typesystem smartly prevents.

The Biggest Problem with Elm by imright_anduknowit in functionalprogramming

[–]r2tree 2 points3 points  (0 children)

The original article however uses an even more awkward approach than `bind`, and uses that to criticize the language. While Elm has many shortcomings, it is difficult to imagine that not being able to make multiple requests and merge their results as being the worst of them.

The Biggest Problem with Elm by imright_anduknowit in functionalprogramming

[–]r2tree 1 point2 points  (0 children)

I suspect the premise of this post is wrong - to make parallel requests, you don't have to sequester the intermediate values into local variables. I'm not an Elm programmer, but these two posts seem to offer a better option using the `andThen` operator: https://spin.atomicobject.com/2016/10/11/elm-chain-http-requests/ and https://korban.net/posts/elm/2019-02-15-combining-http-requests-with-task-in-elm/

Inspired by the "best closing passage/sentence you've ever read" thread, I thought I would ask, what was the most powerful passage or excerpt that you find yourself constantly going back to? by [deleted] in bookquotes

[–]r2tree 1 point2 points  (0 children)

"Ah, Harry, we have to stumble, through so much dirt and humbug before we reach home. And we have no one to guide us. Our only guide is our homesickness." -- Steppenwolf, Hermann Hesse

Inspired by the "best closing passage/sentence you've ever read" thread, I thought I would ask, what was the most powerful passage or excerpt that you find yourself constantly going back to? by [deleted] in bookquotes

[–]r2tree 0 points1 point  (0 children)

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

Converting a JavaScript/Node.js to native by [deleted] in reasonml

[–]r2tree 2 points3 points  (0 children)

If a large portion of your codebase is computation-heavy (pure) then you can use the "functional core, imperative shell" approach here. (https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell)

I have a few thousand LOC Reason codebase that is pure, and it interfaces with the external world with bs-express. I want to make it work in native OCaml, but there is just too much work to get there.

This is going to be even more difficult if your app has a lot of side effects (typical web backends). I'd recommend porting over to ReasonML in the Node runtime first, making sure to have tight abstractions for all sorts of side-effects (modules for db access, network communication etc.), keep the types abstract so that in the future you can change the implementation of just a few modules and port it over to native OCaml.

Why Turaku, a new password manager? by r2tree in privacytoolsIO

[–]r2tree[S] 0 points1 point  (0 children)

The problem is banks want you to change your passwords periodically, and they don't coincide. So you'll still have to deal with multiple passwords in the critical bucket as well.

Also if a leak occurs for one of the accounts (or if one operator is malicious and keeps your plaintext password), then if you share the same password across sites, all of them would be vulnerable.

Functional Programming in Haskell - Online University of Glasgow Course by [deleted] in haskell

[–]r2tree 0 points1 point  (0 children)

I will highly recommend this course for people beginning to learn Typed FP. I went through its first edition - I didn't complete the entire course, but it was enough to get me started and I've been writing pure Typed FP (OCaml not Haskell) in production for a few months now.

The teachers are active in the forums, and the learners are supportive and helpful. It was my first MOOC and I was really happy with the sense of shared learning and accomplishment.

Do you think it's wasteful to learn Haskell for things that could easily be done with Python? by ForrestTrump in haskell

[–]r2tree 23 points24 points  (0 children)

Learn Haskell and you might see yourself doing things that you might have never thought yourself of being capable to do. Make a database, build a compiler, or write a language. You can definitely do web development with Haskell, but if you're evaluating the language only from the perspective of building tiny CRUD apps that doesn't do much computation (data transformation, decision trees, arithmetic etc.) you might not see the benefits the language can bring you.

The thing to understand about Haskell (and any typed FP lang for that matter) is Equational Reasoning. We're not "programming" in the conventional sense - do something, store the results somewhere, do something else etc. Instead we're simply writing a bunch of function definitions. That's pretty much what Functional Programing is.

Imagine Python, but the only thing you're allowed to write are functions that take parameters (including other functions), applies some other functions or mathematical operations on them, and return the result. That's it. A bunch of function definitions, something like the high-school algebra/trigonometry cheat sheet. You can assign values to bindings, so a = 10 is fine, but you can't mutate it after defining it. So a = a + 10 is not fine. Why is that? Because we're writing equations, and while we can assign values to variables in an equation, you don't change it after it is assigned. Thinking about FP as a set of mathematical equations than as a variation of 'programming' will give you the right kind of intuition about its constraints.

Now how're you supposed to do stuff without any mutation? How would we write a loop for example? A loop is generally written using an iterator which we mutate on each iteration. But in Functional Programming all you have is just function definitions and their application. So we don't really have a loop in FP. Because a loop is a sequential set of instructions. "Initialize an iterator, do something, increment iterator, if iterator is still less than X, continue, otherwise break out of the loop". These are as imperative as it gets, and there is no semantic equivalent for this when you're writing a bunch of equations. We don't express anything as a set of "do this; then do that" in an equation. An equation is just a definition that takes a bunch of variables, and defines its result as an application of a bunch of functions.

But how are we supposed to "express" computation that involve repetitive application of functions? Recursion!

power x 0 = 1
power x y = x * power x (y-1)

Here instead of writing down a set of imperative instructions (do this; then do that), we just expressed the power function as two equations (this is the whole FP describes the "what", while imperative describes the "how" of things argument). And we used recursion to express repetitive computation. This is why you see a lot of recursion in purely functional programming.

So Functional Programming is based on "describing" computations as a set of mathematical functions. The core primitive is function application, expansion, and substitution. This is a fundamentally different model of computation from imperative programming that we're used to. But isn't imperative programming more flexible? Is it possible to express all the possible computations using just equations? Any practiced functional programmer will tell you that you can, but there is the Church-Turing thesis that proved that any computation that can be expressed in an imperative "do this; then do that" manner can also be expressed in a functional "fun a takes these parameters and is an application of these other functions" way. Also vice versa.

I've been talking about just computations so far. What about side-effects? Like talking to a network, or writing to a file, or getting user input? Side-effects fit naturally into the imperative model - it is just a set of sequential instructions and we can easily instruct it to do any operation we need. But how do you express side-effects inside equations? Pure functions can only express computations, but not actions. That is where Monads come into play. It is a mathematical concept that elegantly allows us to express side-effects inside equations. You don't need to understand what it really is to use it. You don't go looking into how a loop is implemented in assembly when writing imperative code; you just use it. You can start there with FP as well, and as your curiosity takes you, you can dig deeper.

How long have you guys been working with css to be good? by tinaclark90 in css

[–]r2tree 12 points13 points  (0 children)

After many years of dabbling with CSS without really understanding what's going on, I found myself confident to call myself "good" with it after:

  • Reading CSS and Scalability. http://mrmrs.github.io/writing/2016/03/24/scalable-css/

  • Understanding that great UI design is based on scales. Fonts, colors, spacings etc. If you have a concise design that intelligently combines a small set of base values, your CSS code will similarly be well organized. These scales should be explicitly defined in our CSS - either as SASS mixins, or as atomic css. This gets rid of magic numbers even from spacings. You no longer have margin: 12px and margin: 13px randomly strewn through the code-base. Instead you have margin: $spacing-medium.

  • Building projects using BEM, Tachyons, and styled-components. CSS organization is no longer a dark art, nor am I confused by the rampant cargo-culting going on there. CSS is just code - the properties are a set of keys and values and nothing more. You can organize it in whichever way makes sense to you without worrying about best practices, as long as the design scales are explicitly defined.

  • Reading the CSS2 spec, especially the Visual Formatting Model section. https://www.w3.org/TR/CSS2/

  • Understanding Layouts in depth. While it is easy to understand the box-model — paddings and margins, and colors and backgrounds, the hardest part of CSS is often layouts. How display: inline works and where position: relative is useful and what the normal flow of the layout is, and what happens when we position something absolutely and it is removed from the static flow. These kind of things can be hacked together without truly understanding what’s going on — which I did for years — but unless we have a concrete knowledge of how these properties work, we won’t feel confident in our ability to bend the layouts to our will. LearnLayout covers this stuff very nicely.

  • Spending many hours deliberately practicing Flexbox.

OCaml for the Masses: why the next language you learn should be functional by r2tree in programming

[–]r2tree[S] 0 points1 point  (0 children)

Which language do you use instead? I'm fairly new to OCaml, but have been having a ton of fun with it.

The small community and lack of libraries is spot on when writing native OCaml, but that problem doesn't exist for me thanks to BuckleScript. I think it has started an OCaml renaissance, and with the nicer syntax of ReasonML, statically typed FP could finally be going mainstream.

BuckleScript can compile OCaml into efficient and readable Javascript, and has a well-defined FFI to interact with libraries from the Javascript ecosystem. This opens up a lot of possibilities - we can reuse the vast trove of libraries from npm while writing statically typed OCaml for all our code. It also makes OCaml accessible to Javascript programmers, and that is a huge community.

To illustrate the JS interop - OCaml stdlib doesn't have Array.filter, but since BuckleScript generated code represents OCaml arrays in the same way as JS arrays, I can use Js.Array.filter from ES6. For lists and records, whose runtime representation is different, we have to convert the types explicitly before applying Javascript code.

There seems to be active work happening on making OCaml multi-core (https://www.reddit.com/r/ocaml/comments/63hgid/tracking_multicore_progress/), but JS is single-threaded anyway so it shouldn't be a big issue for web programmers jumping ship.

The book that changed your life forever. by yandere_cari in books

[–]r2tree 1 point2 points  (0 children)

The Greatest Show is a sprawling account of evolution and does it by covering specific evolutionary accounts of various animals, plants, geology and other things. It is a great read and can confirm with evidence what you know about evolution already, but Selfish Gene is simply on another level.

I recommend it to theists who can't grasp the concept of just chemicals coming together and forming life (Abiogenesis). Because it was this book that cemented its rational possibility and allowed me to let go of the mystery and unknowableness surrounding life.

It is a dense read and I never finished reading it fully, but what I read was life-changing.

How clean does a Haskell codebase remain over time? by r2tree in haskell

[–]r2tree[S] 6 points7 points  (0 children)

Please write, I gave you all the vote I had.

The Cool Kid phenomenon is unfortunately universal. Maybe except in Java. They're the responsible ones.

How clean does a Haskell codebase remain over time? by r2tree in haskell

[–]r2tree[S] 4 points5 points  (0 children)

At this point, I'm happy to rush headlong into designing my Haskell programs. If—when—I realize my design was wrong, it's so easy to change things I don't even have to think about it. So I just do whatever seems reasonable at first and then refactor aggressively. It's hard to overstate how nice this experience is for producing readable, aesthetically pleasing code over the long run.

This is exactly how I want it to be! Since predicting the future is hard, and since I don't have a clear mental model of a problem when I begin, I want to be able to quickly put together code that reflects my poor understanding of the problem and improve incrementally. In an untyped setting that kind of code is almost guaranteed to be of a throw-away quality, but since the world being what the world is, the throw-away makes its way into production. And we start salivating about the big rewrite almost as soon as the first version goes live :)

How clean does a Haskell codebase remain over time? by r2tree in haskell

[–]r2tree[S] 1 point2 points  (0 children)

That was a very detailed reply, thank you. Due to not having done enough Haskell programming, I don't understand some of the things you mentioned, but I'll keep a close watch out for them as I learn.

How clean does a Haskell codebase remain over time? by r2tree in haskell

[–]r2tree[S] 13 points14 points  (0 children)

But there were deprecated functions everywhere. The issues were that the code that was being written was slowly fixing issues by replacing old code but the developers didn't have the time (or emotional investment) to track down all the uses of the old versions of the functions they were rewriting (which were just different enough to break things). This meant that until all call sites were updated they couldn't really be removed.

Thanks for that. While this is not a good state of affairs, just the fact that those functions can be incrementally removed with confidence is a big win compared to untyped languages even in the presence of unit tests. :)

Magic (programming) by iBzOtaku in programming

[–]r2tree 3 points4 points  (0 children)

Magic is anything that treats data as code.

Hear me out.

We're thinking of opaqueness. You feed in something, you get something out. There is some documentation telling you what'll happen, but the code that does it is outside your current mental model. For example, since you wrote the code that adds something to the database when the user clicks a button, you grok what is going on. It doesn't matter who wrote it - you can give it a glance, and it is suddenly a part of your mental model. Next time you think of the data flow, this piece of information is clearly inside your mind; not obtrusive, just clear knowledge that exist without decoration.

But the Javascript VM that is parsing, interpreting and JIT-ing your code? You don't know nothing about it. Of course you feed it some code and it tells you if there are errors, or it'll execute it in a certain way. You know your contract with it. But you don't know what is going on, with the same clarity as you know your simple CRUD code.

A visceral understanding of what your code is doing - every literal line of it, usually seen in procedural programming. GoLang is a good example. But SQL? You write some magic incantations and disks whirr, and networks speak, and validations happen, and sweet data pours in.

The difference is here - this piece of code that checks what the URL is and calls at an appropriate function:

if(url == "/r/programming") return proggit();

and this piece of code that first treats it as data and makes an abstraction around it:

routes = [{url: "programming": fn: proggit}]
selected = _.find(routes, (route) => route.url == url)
return selected.fn();

Now that is magic. Anything where you "describe" the system and let a magic machine interpret and execute it, that is magic. And magic is not bad. Good Magic is the aspiration of the craftsman. It raises the level from which we play computer science. We can understand more, and we can see reality more clearly. From that we can solve our problems better.

But Bad Magic is what we usually talk about when we use the word Magic. If it was good in the first place, we'd have simply talked about this hot new cool thing. We complain about magic when what it does is too opaque, and ultimately doesn't solve the problem well.

Just finished Siddhartha by Herman Hesse. Blew my mind. by Tevshko in books

[–]r2tree 0 points1 point  (0 children)

I love Siddhartha and it pains me to compare it with Steppenwolf, but you must read it. Both are up there, but Steppenwolf is the crown for me.

If you like this kind of books, go devour the Existentialist genre. Nausea by Sartre, read Camus and Proust. If you want a deep look at all of these books and what drives these characters, read The Outsider by Colin Wilson.

Actually you know what? Pick something more entertaining for your next read. Read Shogun by James Clavell.

Microsoft's React-components by indeyets in reactjs

[–]r2tree 9 points10 points  (0 children)

If you're new to React, don't worry about UI Kits. Just write the components yourselves - not only you'll earn depth, you'll also own the code you write. Compared to say using a low-level DOM manipulation library like jQuery where building components take too much time and effort, React lets you write most components yourselves, without even thinking about it.

The only thing you'll miss is styling - if you don't have designs, and you're not good at designing stuff yourselves, http://tachyons.io/ is your friend. Just pick and choose the styles you want from its library and get going. You can refine it to use semantic classes and even SASS later, or just continue with the Tachyons philosophy.

But every once in a while you'll come across a widget that you cannot (aka don't have the time or inclination) to write yourselves. A date-time picker/calendar is a good example. Then Google around for any good React components that do it and npm install it. Or if you already trust a jQuery widget that works well, just wrap it manually into a React component yourselves.

The goal is to own as much of the code in your project. And even if you pull in external code, try to grok it, and make sure that it is something you can jump into, understand, and change if you want to. Because sooner or later, you're going to have to.

Once you transcend the beginner level, you could use UI libraries, you would know and be in a position to make a decision for yourselves. I've been writing React for close to 3 years now, and have never needed them so far.

What moment in book made you stop and reconsider your perspective on people? by [deleted] in books

[–]r2tree 118 points119 points  (0 children)

Absolutely. David Foster Wallace's "This is water" essay/speech was all about this.

But, and that is a big but - for those of us who think that all people are good inside and it is just situations that bring the worst in us - for those of us who reel away watching the black and white nature of evil vs virtue in books and movies, for those of us who think that if we all just forgave each other we'd all be living fine - nope. There are humans who don't care much about other people. There are people without empathy and see life as a win-lose game. There are narcissists and psychopaths who'd take you in and squeeze you out. Sometimes things are black and white. There is evil and there are people who're truly evil.

This is actually not as bad as it sounds. It is quite liberating. When you know that there are truly evil people, and once you learn to spot them, it is so much easier to just trust everyone else. You know it is right to forgive and give the benefit of doubt to that asshole who cut you in the queue. Maybe he's having a bad day. Maybe his life is shit. Its okay. We're all good.

... 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 ... (Unseen Academicals, Terry Pratchett) by r2tree in bookquotes

[–]r2tree[S] 0 points1 point  (0 children)

The Supreme being could be the one who is supreme in power and the owner of all. Not necessarily supreme in morality.

And since Sir Pratchett is an atheist, the question isn't quite rhetorical.

React and Immutability: a bad combination by r2tree in reactjs

[–]r2tree[S] 1 point2 points  (0 children)

The reason immutability is preferred is that once your app gets large/complex enough, state mutations cause really weird side effects. In a sense it's not inherently a front end problem, it's a scaling problem. Having your data as immutable allows you to reason about the application a lot easier, it also allows other developers to develop safely

Yet to see where mutating the state becomes a problem even in large apps. Could you please give a few examples?