Why do you need all this theory when you can use simple imperative languages? for staff in company.staff: for pet in staff.pets: if pet.type == 'cat': print(pet.name + " belongs to " + staff.name) I don't understand why functional languages are used at all.
Generalizing 'jq' and Traversal Systems using optics and standard monads
31–40 of 102 posts
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#32Earlier quoted context omitted.
Because it is easier to reason about data transformations. Here when I see loops and conditionals it is confusing because anything could be happening. company.staff.filter(notCats).forEach(printMessage) has more information of what is going on for example imho. But there is a lot more to it.
How would you define the `printMessage` function? The `pet` object doesn't have context about `staff`, and the `filter` function is filtering staff, not pets. It could return staff that have both cats and dogs, so it would incorrectly print dogs.
{company: {staff: [{..., pets: []}]}}
And what we want to do is to produce a list of all the pet cats with its owner name.
[{cat: "bla", owner: "bla"}...]
or
[{owner: "bla", cats:[...],...}, ...]
So I guess what Im trying to explain is that what is important is the change in the way of thinking about problems. When you think of them as data transformations there is a whole lot of possibilities that open. And it is not more expensive because you even have things like transducers. When you abstract away the iteration you are able to compose much more easily.
And to answer your question directly in my example the print function would print for each cat belonging to the staff which is not great flattening would be more elegant. What I wanted to convey is thinking in data transformations and abstracting away the implementation details of the iteration.
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#33Earlier quoted context omitted.
LINQ is definitely a precursor, and has tons of fantastic ideas. It's unfortunate that Microsoft didn't continue to invest heavily into this as it's rarely mentioned nowadays.
I'm not sure I'd call LINQ a precursor when LINQ itself was based on haskell's monadic list comprehensions. monadic list comprehensions aren't quite the same thing as optics, however.
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#34Why do you need all this theory when you can use simple imperative languages? for staff in company.staff: for pet in staff.pets: if pet.type == 'cat': print(pet.name + " belongs to " + staff.name) I don't understand why functional languages are used at all.
That said, I'm presently struggling with AST transformations and other fun stuff in Haskell, so I completely agree with stating it imperatively. It's far, far easier to learn and read simple imperative code.
That's why in my language Tenet[1] I'm trying a hybrid approach: the underlying representation is immutable, but the language uses ordinary control flow and mutation.
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#35Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#36Earlier quoted context omitted.
What's wrong with functions? A function `printCatsBelongingToStaff()` is much easier to read than a line of functional code. I don't understand what you mean by "analyzed much better" and "neat safety guarantees". Is my code hard to analyze or unsafe?
Your code is impossible to analyze. Console.log is a side effect. For loops can be easily mapped into functional constructs, but not your snipped does not compute anything. It's not a function.
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#37"Optics" and "lenses" seem like such bad names just to be able to make a "view data through a lens" pun.
1. The analogies made do hint at their meanings.
2. But at the same time, the names are more proper nouns than definitions. For something so abstract, it's better to give it an opaque, easy-to-remember name than to give it a "better" name that maybe oversimplifies what it is.
This is basically the "Functor" vs "Mappable" argument.
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#38Earlier quoted context omitted.
I wonder how these "optics" compare to .NET's Language Integrated Queries (LINQ) (see https://en.wikipedia.org/wiki/Language_Integrated_Query )
LINQ is definitely a precursor, and has tons of fantastic ideas. It's unfortunate that Microsoft didn't continue to invest heavily into this as it's rarely mentioned nowadays.
Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#39Why do you need all this theory when you can use simple imperative languages? for staff in company.staff: for pet in staff.pets: if pet.type == 'cat': print(pet.name + " belongs to " + staff.name) I don't understand why functional languages are used at all.
The theory lets compilers catch a ton of bugs at compile time. When you can get a functional language to type check, it really does Just Work. And when you limit side-effects, you know another function isn't going to monkey with something it's not supposed to. That said, I'm presently struggling with AST transformations and other fun stuff in Haskell, so I completely agree with stating it imperatively. It's far, far…
Not all functional languages have static typing. Also type checking helps, but saying that if the types check out it just work it pushing it IMO.
No type checker will catch this error:
sqrt :: double -> double
sqrt x = x
sqrt 10Re: Generalizing 'jq' and Traversal Systems using optics and standard monads
#40Earlier quoted context omitted.
Functions are composable. Your statement is not. If I would ask you to create a snippet that searches for cats, another one that searches for dogs and a third one that searches for staff that owns both a cat and a dog you will either duplicate a lot of code or end up with functions. Now if you restrict yourself to not introduce any side effects, the interpreter can be proven correct, the execution can be analysed muc…
What's wrong with functions? A function `printCatsBelongingToStaff()` is much easier to read than a line of functional code. I don't understand what you mean by "analyzed much better" and "neat safety guarantees". Is my code hard to analyze or unsafe?
Functional programmers (of the Haskell bent, at least) would prefer that they not have to write printCatsBelongingToStaff, printCatsBelongingToCustomers, printCatsBelongingToChildrenOfStaff, printDogsBelongingToStaff, renameCatsBelongingToStaff, &c. They would instead prefer to write print, rename, staff, customers, cats, dogs (or perhaps just pets, with an ability to discriminate between cats and dogs...), children, and compose. They would also prefer to write these functions in such a way that the computer (rather than the human) can analyze the resulting compositions and guarantee that they operate in the way you would expect (with "expect" being precisely codified between the types of the functions and a succinct set of laws).
The big picture here is that computers are much faster and more consistent in their checking ability than humans, so the more things we can encode in our programs in a computer-checkable way, or in laws that we can prove are preserved under composition, the more reliable our software will be on whole.