Live data from Hacker News

Codata in action, or how to connect FP and OOP

javiercasas.com

21–30 of 58 posts

Re: Codata in action, or how to connect FP and OOP

#21
This paper on "Object Algebras": https://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf

is a great example of using ideas from functional programming and category theory to improve on the visitor pattern, such that the expresson problem can be solved.

The value of such mathematics is that it enables us to formalise some of these patterns and generalise them.

Re: Codata in action, or how to connect FP and OOP

#22
post #12

" (...) - In an OO language, you can add a new case by creating another subclass and implementing the methods. But, if you want to add a new function to a datatype, you have to add it to the superclass and implement it on all the existing subclasses, which means modifying a lot of files and recompiling most of the program. - In a FP language you can add a new function to an existing datatype just by adding a function…

Solving the expression problem requires maintaining static type safety. AFAIK Julia doesn’t do this because it’s dynamically typed.

I don't think you can classify Julia like this.

It's kind of both.

Julia has types on bindings, in that sense it is statically typed.

Re: Codata in action, or how to connect FP and OOP

#24
post #12

Earlier quoted context omitted.

Solving the expression problem requires maintaining static type safety. AFAIK Julia doesn’t do this because it’s dynamically typed.

I don't think you can classify Julia like this. It's kind of both. Julia has types on bindings, in that sense it is statically typed.

“Julia is squarely in the dynamic camp” - Stefan Karpinski, Julia co-creator

https://stackoverflow.com/a/28096079

Re: Codata in action, or how to connect FP and OOP

#25

Earlier quoted context omitted.

I don't think multiple dispatch fixes this problem in any way. The idea here is that you can have an opaque interface. Then, adding new implementations of that interface is very easy. But, if you want to extend the interface, you need to modify all of the existing implementations. Multiple dispatch suffers of this problem just as much as single dispatch. In the other case, you have a transparent interface - anyone ca…

Some Rust libraries use a trick to make sum types extensible without introducing breaking changes when a new invariant is added. There is a private/undocumented invariant in the type so every pattern match over the type must have a default/catch-all/wildcard branch (e.g. it is not possible to do an exhaustive match by naming all existing variants). By having a default branch, the match is always exhaustive and there…

Forcing a default case is a big step back towards dynamic typing.

Re: Codata in action, or how to connect FP and OOP

#26

" (...) - In an OO language, you can add a new case by creating another subclass and implementing the methods. But, if you want to add a new function to a datatype, you have to add it to the superclass and implement it on all the existing subclasses, which means modifying a lot of files and recompiling most of the program. - In a FP language you can add a new function to an existing datatype just by adding a function…

Any OOP with inheritance does multiple dispatch. Java, C++ vitual functions, python via ducktyping. The article's concern is real but overstated in my opinion. When adding a new function in a hierarchy you'll either have a good default or you'll be implementing via type matching branches or 10 implementations in each type behind multiple dispatch. The difference, to me, is minimal.

> Any OOP with inheritance does multiple dispatch. Java, C++ vitual functions

This is incorrect. C++ and Java are typical examples of languages that lack multiple dispatch, but are able to emulate it using the visitor pattern, as tsimionescu already mentioned.

https://en.wikipedia.org/wiki/Multiple_dispatch#Emulating_mu...

Re: Codata in action, or how to connect FP and OOP

#27

" (...) - In an OO language, you can add a new case by creating another subclass and implementing the methods. But, if you want to add a new function to a datatype, you have to add it to the superclass and implement it on all the existing subclasses, which means modifying a lot of files and recompiling most of the program. - In a FP language you can add a new function to an existing datatype just by adding a function…

Relevant presentation by one of the creators of Julia: https://www.youtube.com/watch?v=kc9HwsxE1OY

Re: Codata in action, or how to connect FP and OOP

#28

" (...) - In an OO language, you can add a new case by creating another subclass and implementing the methods. But, if you want to add a new function to a datatype, you have to add it to the superclass and implement it on all the existing subclasses, which means modifying a lot of files and recompiling most of the program. - In a FP language you can add a new function to an existing datatype just by adding a function…

I don't think multiple dispatch fixes this problem in any way. The idea here is that you can have an opaque interface. Then, adding new implementations of that interface is very easy. But, if you want to extend the interface, you need to modify all of the existing implementations. Multiple dispatch suffers of this problem just as much as single dispatch. In the other case, you have a transparent interface - anyone ca…

There is no need to modify existing implementations when extending an interface using multiple dispatch.

You would need to add the required implementations, but there's really no way around that since the logic has to go somewhere.

And as soon as you start actually dispatching on multiple arguments, using sum types to solve the same prolem quickly turns into spaghetti.

Re: Codata in action, or how to connect FP and OOP

#29

Earlier quoted context omitted.

> Any OOP with inheritance does multiple dispatch. Java, C++ vitual functions, python via ducktyping. Java, Python and C++ require Visitor machinery that you ahev to write, for each case, to implement multiple dispatch (and Visitor only works for double dispatch, if you want more than 2 arguments you need even more boilerplate). Julia and CLOS essentially have that machinery built in. In case this is not clear, multi…

> Java, Python and C++ require Visitor machinery that you ahev to write, for each case, to implement multiple dispatch (and Visitor only works for double dispatch, if you want more than 2 arguments you need even more boilerplate). Julia and CLOS essentially have that machinery built in. we're in 2020 using value = std::variant ; void foo(value a, value b, value c) { struct { void operator(int, float, string) { } void…

Well, you can write Fortran in any language.

It's far from the same thing though, less convenient and less flexible.

Multiple dispatch doesn't require a centralized declaration of the possible types and allows putting implementations in different files.

Re: Codata in action, or how to connect FP and OOP

#30
post #24

Earlier quoted context omitted.

I don't think you can classify Julia like this. It's kind of both. Julia has types on bindings, in that sense it is statically typed.

“Julia is squarely in the dynamic camp” - Stefan Karpinski, Julia co-creator https://stackoverflow.com/a/28096079

Well, that's like...his perspective.

It's a spectrum, not either or.

Julia and Common Lisp are somewhere in the middle.

Post reply on HN