Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

    Assume that a = 1 is true
I just don't read code as I would a mathematical proof. I think in terms of what memory locations are equal to what in the stack, or the heap, and what is the lifecycle of that data in that memory address.

When I read "int a = 1" in C#, I implicitly translate that to "take a 4 byte piece of memory on the stack, and set it equal to 1". I don't think in the abstract sense of a formula.

When I see a class like:

    class Foo {
        int x = 2;
        string xyz = "Hello";
    }
    
    var foo = new Foo();
I read this as "allocate a chunk of memory big enough in the heap to insert a 4 byte integer and an 8 byte pointer. Set that 8 byte pointer equal to a static chunk of memory where the "Hello" string is pooled.


> When I read "int a = 1" in C#, I implicitly translate that to "take a 4 byte piece of memory on the stack, and set it equal to 1".

I think that's overspecifying a bit. It could be kept in a register rather than the stack. And due to to the Single Static Assignment transformation that modern optimising compilers do, variables don't correspond exsctly to registers anymore; each time you modify the variable, it becomew a new variable, and then the compiler removes or changes extraneous modifications and dead code. It only keeps track of the values that move through the code. You could really only count on variables corresponding exactly to stack space registers before the SSA form existed.


> I just don't read code as I would a mathematical proof.

That's fine, although I'd say that FP is probably just not for you. It's very much a style of programming that lends itself more towards "programming is akin to proofs" than "programming is about manipulating things on a von neumann architecture". Neither is an incorrect view of the world, but they do represent different ways of reasoning about things and it's better to use a language more suited towards one way of thinking.


To be honest, when I read e.g. Haskell code, I don't get the sense of a mathematical proof at all, not compared to proof assistants like Isabelle/HOL, Coq, or Lean. It looks more like abstract, high-level wizardry, casting that transform the output of one function into the correct type so that it can become input into another; and yet it's very abstract typing, nothing like proof-assistant tactics (though I admit I'm not all that experienced with proof assistants either).

I think immutability is more about making it easier to reason about the code than mathematical proofs specifically.


> That's fine, although I'd say that FP is probably just not for you.

That's just gatekeeping.


It’s not, but you’re free to believe that.


This is the biggest hurdle for a lot of people, at least for me. The immutability.

IF you have grown up doing objects, or C#, and thinking with variables. Then 'a=1' means a memory for variable a has a 1, and you should be able to change that. But it is really a like a function where the function returns a 1.

'let a = 1' is not assigning the value 1 to variable a.

'a' is a function that returns a 1.

I think this is biggest reason why people trying to learn functional programming in languages that don't enforce immutability, have a harder time than with languages that do enforce it.

Like moving to another country, and the people around you purposely don't speak English so you have to learn the language. If the did speak English to help you, then you wouldn't learn the language.

Enforcing immutability is like this.


Well, most people learn about variables [1] before variables [2], so I find it funny that you think of the mutable ones as English.

Mutable variables are better explained as slots or cells, I think. Both OCaml and Rust have a concept of ref cells, for example (and they entirely replace mutable local variables in OCaml).

1: https://en.m.wikipedia.org/wiki/Variable_(mathematics) 2: https://en.m.wikipedia.org/wiki/Variable_(computer_science)


F# has ref cells too but they are discouraged in favour of the mutable keyword


I know, inherited from OCaml. I was talking more about which metaphors to push for instead, rather than any actual data structure.


I got the concept of immutability, but I inevitably ended up recreating OOP patterns whenever I tried working with F#. I do Asp.net WebAPI Projects and trying to do dependency injection ends up just translating C# to F# code rather writing idiomatic F#. I just don't know if HTTP is something F# is really good at doing. I can see it being really useful if you were writing something math-heavy


I make web apps with the SAFE stack. Using idiomatic F#, the experience has been great.

I can imagine that trying to translate C# to F# would be horrible. That is going against the grain.

I'd encourage you to have a look at the SAFE stack it's really nice to use. https://safe-stack.github.io/


Any particular documents/tutorials you recommend? Feels like SAFE doesn't have a ton of either but I might just be looking in the wrong places. Like I admit I didn't try the Dojo yet because that sounded like a second round of learning not the very basics, but I'm also only eh at web development



Appreciate the links. Fable/SAFE has been something I'm curious about for a while. And I already meant to look at the elmish book but had not gotten around to it.

I've actually gone through most of the Dojo tonight except for the reset button.


I tried using the safe stack, but it seemed like it wasn't up to date with the latest version of .NET. Is that normal? Or did I hit a weird edge case in the ecosystem? (Or was it a case of PEBKAC?)


Yes you're right that they are a little behind. Currently on .Net 6. That is a shame as .Net 7 seems to have made significant improvements to performance.

That said I don't think there are any features that I'm missing out on being at .Net 6.

I think there is a limited number of maintainers of the SAFE template so they might not be able to keep on the bleeding edge. But it's not that hard to update the components to the latest versions. As can be seen on this waiting pull request https://github.com/SAFE-Stack/SAFE-template/pull/564

I should also mention that when I've hit issues with packages not working on the latest .Net version I've asked in the F# slack and twice had the maintainers fix things within a day so it would run at the latest version.


I found the Slack channel to be pretty responsive and friendly. Still, I was a bit bummed because I kept running into issues. Some documentation links were broken and I tried to fix them, but I couldn't get the project to build on Debian. I tried safe stack and had the wrong version of .NET. Once I got the right one, I had issues running the project (turned out the path did not support the "#" character). A lot of the documentation assumed you knew the .NET ecosystem, but I was coming from python. It seemed like I kept hitting sharp edges.

I'm still curious about F#. It has a lot of neat looking features (units of measure, computation expressions, active patterns) and has some of the easiest to read code I've seen. I just don't know if my experience was representative or if it was abnormal. :/


Yeah the .NET learning curve is steep. It's a little worse than some other languages out there. I found the same thing. I came from a Linux background, PHP, Perl and similar.


ah. yeah, if you are doing web programming. then for F#, you would use a library that is really like a DSL for the web. One of the things in practice in F#, it seems the most useful libraries are written as DSL's, so it is like a language extension for doing 'whatever'. To really get these web based ones, need to understand "ELM architecture".

In any case. I get it. If you have done ASP.NET, and C#, then suddenly this F# way of building web pages by programming through combining functions, it is hard to get over the hump. Like brain has to re-change how to think through the whole flow. Really, F# on the web is like ELM.

I like https://websharper.com/

but other use this https://suave.io/


Giraffe is another interesting one to explore: https://giraffe.wiki/

Giraffe is nice because it is itself built "just" as ASP.NET Core Middleware so it plays a bit more nicely than Suave with a mixed stack of C#-defined Middleware.

It's more likely you accidentally fall back into just translating C# patterns to non-idiomatic F# with Giraffe, but it's also nicer when in that case of needing to live in both worlds and use a mixture of libraries built for C# ASP.NET projects.


F# is severely hampered by its standard library, which is object-oriented by design. Some newer things like fluent api's or object initializers are more amenable to F#'s functional style, but on the whole my experience matches yours: as soon as you start interfacing with any .net library, it feels like you're writing in a foreign language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: