How to make the transition from a heavy functional programming background into Odin?

Over the years I’ve been doing a lot of FP, which is the complete opposite of what languages like Odin offers. Even on the FP side, there is a clear distinction between languages that allow side effects anywhere like Clojure and Erlang, and more pure languages like Haskell and Scala with Cats Effect/ZIO.

I’ve done some apps using these principles and they work, that’s all I can say. There is so much control at the type level that a regular developer using just mainstream languages can barely imagine, and they usually have a really hard time grasping the code base.

What I’m trying to say here is the following. I’ve programmed on both sides, and both sides have pros and cons, and this has been the main issue for me. I want the type level control of those languages, but the speed and simplicity of Odin.

Am I crazy? For others that have a similar background, how are you seen programs these days? Every time I create a variable that can be mutated the FP in me screams to make it immutable.

Sorry if this deviates a little from the purpose of the forum, but I’m onboardin on Odin and I have this thing living rent free in my head.

I’ve seen a couple posts now mentioning the same topics that have been addressed in detail without referencing any of the advice given.

  • Get the book.
  • Start some projects.
  • Implement the advice already given.
  • Provide code examples to back up any claims.
  • Ask questions about specifics, rather than continuing to focus on abstract discussions. Abstract ideas cannot be grasped without trudging through the weeds first.

Functional Programming
Read the faq. A procedure is a superset of functions and subroutines. Odin is both with sugar coating.

Types
Basically everything you define in Odin that is not a procedure (though sometimes including procedures), is a type, either implicitly or explicitly (i.e. distinct types). Odin is a heavenly typed language. Spend some time with it and that will become obvious.

Mutable and Immutable Variables
(“Immutability” seems wrong. Prefer “Mutability” )

Odin is actually quite strict on what the compiler will allow to be mutable. There is a clear distinction between heap and stack memory for one. Additionally, scope and context are also clearly defined, with some flexibility to allow for shadowing. Procedures default to immutable variables unless passed as pointers. Constants can be declared easily with “::”. Read about rodata. There’s also type-assertions, panic, etc. Use them.

I’ve worked with many languages and several multi-million dollar projects that involved many moving parts which all utilized there own tech. I’ve been totally taken with Odin for the following reasons:

  1. Simplicity of use and design with heaps of sugar to boot.
  2. More or less, full control of memory usage.
  3. A strong aversion to dependency hell.
  4. An impressive catalog of “batteries included”, which is not a requirement for any language to provide. Back in the day, an extensive library of pre-defined routines was not all that common.
  5. A strongly opinionated creator with the background to warrant those opinions. It’s obvious to me that GB puts a lot of thought and prototyping into the design decisions for Odin, so when he responds, which is often direct (which I also like), you can be reasonably certain that there is a lot more in consideration than what is mentioned. That style of communication, from my experience, comes from a good sense to keep things simple and focused; to not muddy-the-water of the current topic. I want a captain of the ship, with the grit and gumption to make sure she makes it to port so I can focus on the seaman’s life.
5 Likes
  1. Recursion = for loop with extra overhead (in most cases).
  2. When you really need it, Odin is fine with recursion - just like almost every other language.
  3. List comprehension = for loop. Range-Based For Loops
  4. Immutable data is overhyped. What you’re really trying to control is what code can modify what data.
  5. If you really don’t want some piece of data modified, then don’t modify it. (No language will keep you from writing bad code.)
  6. Odin has all the type structures you need. Odin Advanced Types
  7. You can pass procedures to make your own “higher order” types. Procedure Type
  8. If you want to separate your effects from your logic, then separate your effects from your logic.
  9. Pattern matching = switch statement or overloaded procedures. Procedure Overloading
  10. Dynamic arrays are the new lists. They grow from the back, not the front. Dynamic Arrays

Can you clarify this one? I think odin’s dynamic arrays work exactly like C#'s List, C++'s vector or Java’s ArrayList. Am I wrong?

For a generous interpretation of “exactly”, you are correct.

1 Like

Can you clarify this one? I think odin’s dynamic arrays work exactly like C#'s List, C++'s vector or Java’s ArrayList. Am I wrong?

That is correct.

The comparison made here is that when you’re building lists in functional languages, you generally append to the front because they’re implemented as linked lists pointing to the next node/rest of list and doing it that way avoids having to create a new copy of the list with one item added to it.

2 Likes
  1. Immutable data is overhyped. What you’re really trying to control is what code can modify what data.

This. So much this. People think they want immutability because they don’t want spooky action at a distance surprises, and immutability is the simplest and most obvious way to achieve that. Unfortunately you still need to mutate the world state in response to user input, so then the “immutability” turns into confusing workarounds like “reducers” and pass-the-world argument practices that quadratically or exponentially explode the amount of allocations and copying, fragment the heap, thrash the cache, and basically make garbage collection mandatory. At that point, you’re just hiding state management and mutability in the runtime and making a program that your CPU hates running.

1 Like

I actually had to comeback to Odin because Ocaml is so inefficient to do a lot of things for gamedev & performance intensive purposes where mutable data is crucial to have.

If you are so desperate about FP immutability, better be back on ML strictness rather than be with Odin I think.

Honestly I don’t think it’s that hard to go from functional to procedural and back.
The only thing that is necessary is to instead of thinking in “what functions should I call and how should I structure my data” you reframe it into “what steps should I have to do one by one to achieve this and what information do I need to pass around so that this task is able to be accomplished?”

I still think immutability is valuable and being able to properly use tagged unions and enums to model the state changes you need is still useful, but mutability is a lot less frowned upon when you’re just deconstructing things into sets you need to do instead of into state transformations that are passed around.

Besides this, I think if you’re not used to managing memory being able to efficiently do so and using different allocation strategies will be more challenging than just writing things procedural imo just because doing things step by step is very natural for people.