Earlier quoted context omitted.
> However, that doesn’t necessarily imply an all-or-nothing approach where either you’re in a pure function or you can do anything with anything. To elaborate this point I'd say that the most important practical use of all that "monad mumbo-jumbo" in Haskell is that you can tag your functions with what they can and can't do and then the type system tracks this for you: -- pure function f1 :: Text -> Int -- can fail f…
The trick seems to be how to implement this kind of idea in a composable way, so we can still have a clear, modular design and write generic, reusable code even in the presence of several different types of effect. IMHO, the research into type and effect systems in recent years has been promising, but also shows that this is not an easy problem to solve. I’m hoping that in a few more years we might see a new generati…
Three Months of Go from a Haskeller’s perspective (2016)
151–160 of 162 posts
Re: Three Months of Go from a Haskeller’s perspective (2016)
#152Earlier quoted context omitted.
Definitely! I couldn't get my head around why people like untyped languages, but I keep an open mind on it. I won't close off that they could be better, if the right patterns/practices are used (whatever they are!)
I joked with a friend that as people get older they start to prefer static typing. I personally don't have a preference, it depends on the application. I think it's obvious what are the advantages of static typing so let me rant about what is for me the main disadvantage: as soon as you have an advanced type system people will try to get creative writing code in the most abstract possible way. It's inevitable. It's t…
But it means your web scraping code, crud app, {some other boring everyday app} or whatever is now adorned with all this deep mathematical complexity that if you just used nodejs or something it would be easier to understand.
Premature optimization is probably a good term for it, because the good think about haskell is it is easy to make refactoring. Make things specific now and more general later, and it should be backwards compatible for the most part.
But making things into "arrows" is part of the sport I think.
Re: Three Months of Go from a Haskeller’s perspective (2016)
#153Earlier quoted context omitted.
Go is incredibly readable I find. Yes, you tend to find yourself writing a lot of code because of the lack of generics, but that is being fixed as we speak. Generics has a draft and it looks nice from a Go developers perspective. And Go let's you communicate by copying. That's what a Channel is. Pass a struct and that is copied. Pass a pointer and the pointer is copied. The thing it points to isn't copied for glaring…
> And Go let's you communicate by copying. That's what a Channel is. Pass a struct and that is copied. Pass a pointer and the pointer is copied. The thing it points to isn't copied for glaringly obvious reasons. Copying large structs is not ideal, but passing a pointer to the channel means the other side of the channel can mutate that data. If Go had immutable types, you could pass a constant pointer, allowing the ot…
Not quite. I am suggesting a tagged union. Not a runtime type check.
You'd check the tag.
Some language only support the runtime type-checked version of union types. That's a bit silly. For example, it makes it much harder to write a function that may either error out itself, or produce an error message as its bona fide value.
Re: Three Months of Go from a Haskeller’s perspective (2016)
#154Earlier quoted context omitted.
Regarding the example in your first point, you are still sending a reference `m` of the map. If you wanted to send an immutable type, you could declare the channel to only accept struct values (and not pointers to structs) and you'll get your desired behavior. Here's a playground for reference: https://play.golang.org/p/U2tYZVTtUf-
Given that there is no way to make a non-pointer map in Go, there is no workaround for the example they gave. The broader point is that there is no way in Go to ensure that data passed over a channel will not be modified concurrently without modifying the type of the data specifically for the channel use case. A deep_copy() primitive would fix this.
Re: Three Months of Go from a Haskeller’s perspective (2016)
#155Earlier quoted context omitted.
Given that there is no way to make a non-pointer map in Go, there is no workaround for the example they gave. The broader point is that there is no way in Go to ensure that data passed over a channel will not be modified concurrently without modifying the type of the data specifically for the channel use case. A deep_copy() primitive would fix this.
Right, but they mentioned sending immutable structs which is why I gave the struct example. But you're right that every declared map is a just a pointer. With respect to your second point, I see what you mean but I still don't think that's a negative of Go. You can pass in copied values without having to have a deep_copy() primitive (loop map values and copy to new map, dereferencing a pointer, etc.). Like other part…
Re: Three Months of Go from a Haskeller’s perspective (2016)
#156Earlier quoted context omitted.
Go is incredibly readable I find. Yes, you tend to find yourself writing a lot of code because of the lack of generics, but that is being fixed as we speak. Generics has a draft and it looks nice from a Go developers perspective. And Go let's you communicate by copying. That's what a Channel is. Pass a struct and that is copied. Pass a pointer and the pointer is copied. The thing it points to isn't copied for glaring…
I think even more than the lack of generics, Go is difficult to read because it forces you to mix the error path with the success path in every function which can possibly fail, often making you bubble errors up the call stack manually.
Go has no facilities to would allow you to abstract away the repetitive parts of error handling.
Re: Three Months of Go from a Haskeller’s perspective (2016)
#157Earlier quoted context omitted.
I get your point, but if we're all bad then "bad" loses its meaning. I'm definitely a better programmer than many of my peers, and worse than a whole bunch of others.
We're bad, not in comparison with each other, but in comparison to the external standard of "good enough that we don't need a crutch". In fact, if you want to be a better (less bad) programmer, learn to use the available crutches more effectively.
Or that planes are a crutch for bad travelers who can't fly under their own power.
Re: Three Months of Go from a Haskeller’s perspective (2016)
#158Earlier quoted context omitted.
> I couldn't get my head around why people like untyped languages What do you mean exactly with "liking" untyped languages? I personally program mainly in both a ("cognitively demanding") typed and an untyped languages, and they have different use cases. For relatively small programs, untyped languages are much faster to develop. A program I wrote yesterday in a few hours would have taken 2 to 4 times as much in a ty…
Is that true? A simple program that isn't going to see long term use means I don't have to worry about anything but the happy path, either typed or untyped. And something where I have to nail down the edge cases is easier in a typed language.
Besides the unstructured trees, another example, although more high-level, is interfaces. They're a concept required in statically typed languages (some languages they have a simpler design than others), but not in dynamically typed languages (which have duck typing).
If you have a couple of types that you need to abstract, in a S.T. you'll need to define an interface, the method signatures, which include the return types, and maybe (in lower level languages) the generic types and the super interfaces. Even something as (relatively) simple as generalizing a tuple and a matrix types will require some design.
In D.T. languages, zero effort is required. As long as an object responds to a method (name), it's game.
I think it's not realistic to assume that the concepts that need to be taken care of in a S.T. language are comparable to the ones in a D.T. language. And more concepts imply more cognitive load. And cognitive resources are limited :-)
Re: Three Months of Go from a Haskeller’s perspective (2016)
#159Earlier quoted context omitted.
> However, that doesn’t necessarily imply an all-or-nothing approach where either you’re in a pure function or you can do anything with anything. To elaborate this point I'd say that the most important practical use of all that "monad mumbo-jumbo" in Haskell is that you can tag your functions with what they can and can't do and then the type system tracks this for you: -- pure function f1 :: Text -> Int -- can fail f…
The trick seems to be how to implement this kind of idea in a composable way, so we can still have a clear, modular design and write generic, reusable code even in the presence of several different types of effect. IMHO, the research into type and effect systems in recent years has been promising, but also shows that this is not an easy problem to solve. I’m hoping that in a few more years we might see a new generati…
type FooContext m = (GetTime m, GenUUID m, Log m, Auth m, ReadDB m, WriteS3 m, BarApi m, etc...)
foo :: (FooContext m) => UUID -> m Foo
The main downside is ergonomics, ie. the amount of boilerplate needed, but personally I don't think that's a high price to pay.Re: Three Months of Go from a Haskeller’s perspective (2016)
#160Earlier quoted context omitted.
Prototyping or gluing components together is definitely faster without static typing.
I think this is a fault of language ergonomics rather than static typing. If you are gluing components together, then surely the components have a common interface that uses compatible types. And surely you need to tell the runtime what those types are in some way, even if that is simply by writing them to return appropriate values. In theory, a statically typed language with ideal ergonomics would make that as easy…