Programming thread -

ConcernedAnon

Concerned and hopefully anonymous
kiwifarms.net
As a newcomer, which languages should I learn first? I was thinking about learning C++, but it is a big language, and I don't know if I should start with something else before getting to learn C++.
I don't recommend starting with C++ —though it's very much worth learning, I'd start with something like C# or a scripting language. C++ gets quite complex, and a huge part of the initial learning curve is going to be the toolchain, so if you start with C++ you'll probably end up frustrated just wrangling the compiler and it's many components.

Once you've gotten the hang of common programming concepts, then I'd tackle C++. I personally started with python, and then moved to C++. I found that python —though it taught me an adequate amount of general programming— taught me very little about computers, while C++ taught me quite a bit and that knowledge has been applicable to every language I've encountered since.

Learning an abstract language is a good starting place, but it won't teach you anything about computers, and once you understand the principles of the underlying architecture you can make much better programming decisions.

Edit; also let me recommend C++ for dummies —no, I'm not joking— it's quite a good book to start with, and it's how I started. The best teacher is of course practice, but it's good to get your feet on the ground first.
 
Last edited:

Coolio55

DON'T CALL LUIGI AT 3AM!! *OMG HE RICKROLLED ME*
kiwifarms.net
As a newcomer, which languages should I learn first? I was thinking about learning C++, but it is a big language, and I don't know if I should start with something else before getting to learn C++.
Generally the problem languages have isn't that they're too big. It's that some of them make it easy to shoot yourself in the foot with.
The main issue with languages like C++ is the memory management front where a single mistake can corrupt the heap and fuck everything up. (Although C++ has slightly less booby traps than C)

Also functional programming is for people with broke brains and all assertions of "efficiency" are quashed by the unavoidable fact that all machines are imperative by nature.

I'd suggest Python because it's good for knocking stuff up easily and there's few times where you'll have to refactor everything because you fucked up somewhere (C# is also good but microsoft now owns mono and they're trying their best to funnel everyone on windows into using that POS Visual studio) but keep in mind that a LOT of python's fun aspects are completely foreign to a serious language such as C++ and you'll have to implement them yourself (Some are completely unimplementable for good reason though).
A few examples: Foreach, arrays that auto free memory when they shrink, python's argument system where you can overwrite as many or as little default arguments in whatever order you please, all the wierd stuff in python that allows you to edit object classes in realtime etc.
Also there's a lot of disparity between compilers and that's always fun. (Still more fun than the fact that Rust has a single centralized compiler and package system)

One incredibly important thing with languages like C and C++ is the command line. LEARN IT. Learn how to compile programs via it (How to specify libs and search paths). Learn about the PATH and other environment variables. With C and C++, all you need it a text editor like Notepad++ and a GCC/LLVM (The latter is generally better but still a bit new and not so widely used) installation. Shackling yourself to a bloated IDE is a huge mistake most noobs fall into and it'll fuck with you when you have to switch to a new one or do something wierd that the IDE didn't take into account. IDEs are fine but you gotta learn how it works under the hood first.

Ps. Last word. All of C's (And some of C++'s) wierd memory shit is a feature, not a bug.
Say I'm writing code for the GBA. Yes, the Game Boy Advance. That's the fun of languages like C, you can run nearly anywhere! C++ has support too but you gotta turn off exceptions as they are huge memory hogs. There are a lot of specific hardware addresses that data should be written to display stuff like sprites and tiled backgrounds or output sound. Only languages that allow you to write to arbitrary memory locations can do stuff like this. (For all other memory related shenanigans you can just use malloc/calloc though). There are also several kernal functions that only languages with the ability to use inline assembly can use.
Note that last bit, inline assembly is NOT an ANSI C feature yet most compilers support it with varying standards. This is part of the "fun" that comes with C compilers. (As well as tons of other implementation specific differences)
 
Last edited:

Yotsubaaa

Yeahhh 2020!!
True & Honest Fan
kiwifarms.net
(C# is also good but microsoft now owns mono and they're trying their best to funnel everyone on windows into using that POS Visual studio)
Huh? Visual Studio is one of the best integrated development environments out there. (And I say that as a diehard JetBrains fan who also spends a lot of her time coding in emacs.)

keep in mind that a LOT of python's fun aspects are completely foreign to a serious language such as C++ and you'll have to implement them yourself (Some are completely unimplementable for good reason though).

A few examples: Foreach, arrays that auto free memory when they shrink,
C++11 added a foreach syntax:
C++:
for (auto &val : stuff) {
    // Do things
}
And it even has an explicit for_each() in the <algorithm> standard library:
C++:
std::for_each(stuff.begin(), stuff.end(), func);
The others are more or less fair points. Although I'd argue that C++ arrays and Python arrays lists serve different purposes. Python's lists are sophisticated data structures with all sorts of bells and whistles, whereas C++ arrays are literally just contiguous blocks of memory for the most part.

Actually, one cool thing I really like about Python is the list comprehensions, they're pretty neat (and lispy!):
Python:
[do_thing(x) for x in vals]
Returns a list!

python's argument system where you can overwrite as many or as little default arguments in whatever order you please, all the wierd stuff in python that allows you to edit object classes in realtime etc.
Fair points I suppose. I also agree that keyword arguments are pretty cool. (Though I will say I went on a rant about runtime class reflection in Ruby a while back. The others made some good points back then about it, but I still can't say I'm exactly a fan of the idea.)
 

ConcernedAnon

Concerned and hopefully anonymous
kiwifarms.net
In my experience, it's usually only programmers who are brain damaged by OOP who can't be saved. Everyone else takes to it naturally.
"We need a policy!"
like nah bro, chill, you need a chill monad.
In my opinion the major flaw of OOP is that it treats types as though they are an immutable aspect of data, whereas they are only views into it. Defining everything in a strict way —as OOP tends to enforce— can limit many errors and structure your programs, it only becomes a problem when it begins to limit what you can do. Sadly it often does —you can't iterate over that because it's creator didn't explicitly say you could!— and so people get tied up writing wrapper classes and endless boilerplate trying to convince the machine that the obvious is just that.


all assertions of "efficiency" are quashed by the unavoidable fact that all machines are imperative by nature.
I feel that is important to note. Functional languages are inevitably unrepresentative of the underlying architecture, and while it may be possible for a JITer to optimize the program into something relatively efficient, the language ultimately hides the actual details of the computation and thus inhibits good algorithm choice. This is convenient for the purpose of solving problems in a seemingly sensible manner, but will inevitably lead to inefficiencies as the methods don't match the machinery.

Shackling yourself to a bloated IDE is a huge mistake most noobs fall into and it'll fuck with you when you have to switch to a new one or do something wierd that the IDE didn't take into account. IDEs are fine but you gotta learn how it works under the hood first.
I don't quite agree. I think it's better to learn the language first with an IDE handling the tooling for you, and then learn how the toolchain works. I agree it's essential to understand the tooling, however on the side of pragmatism, I think the complexity of the tooling contrasted with the triviality of their first programs will prove to be a turn off for many newcomers.

I do find it rather funny when functional people get all snobby about their beautiful languages; whose implementations are written in C anyway :story:
You'll never be free of us!
 

garakfan69

Please be patient, I have idiocy
kiwifarms.net
The others are more or less fair points. Although I'd argue that C++ arrays and Python arrays lists serve different purposes. Python's lists are sophisticated data structures with all sorts of bells and whistles, whereas C++ arrays are literally just contiguous blocks of memory for the most part.
The closest C++ counterpart to Python lists would probably be std::vector.
Conversely, you can use C arrays in Python through the array module.

Actually, one cool thing I really like about Python is the list comprehensions, they're pretty neat (and lispy!):
List comprehensions are basically just a little more readable way to do map or filter.
Modern C++ has lambdas and map/filter/reduce style functions, so you can do something like:
Code:
transform(vals.begin(), vals.end(), ret.begin(), do_thing)
 

Coolio55

DON'T CALL LUIGI AT 3AM!! *OMG HE RICKROLLED ME*
kiwifarms.net
Huh? Visual Studio is one of the best integrated development environments out there. (And I say that as a diehard JetBrains fan who also spends a lot of her time coding in emacs.)


C++11 added a foreach syntax:
C++:
for (auto &val : stuff) {
    // Do things
}
And it even has an explicit for_each() in the <algorithm> standard library:
C++:
std::for_each(stuff.begin(), stuff.end(), func);
The others are more or less fair points. Although I'd argue that C++ arrays and Python arrays lists serve different purposes. Python's lists are sophisticated data structures with all sorts of bells and whistles, whereas C++ arrays are literally just contiguous blocks of memory for the most part.

Actually, one cool thing I really like about Python is the list comprehensions, they're pretty neat (and lispy!):
Python:
[do_thing(x) for x in vals]
Returns a list!


Fair points I suppose. I also agree that keyword arguments are pretty cool. (Though I will say I went on a rant about runtime class reflection in Ruby a while back. The others made some good points back then about it, but I still can't say I'm exactly a fan of the idea.)
I know C++11 added a bunch of stuff like that (And the newer C++ revisions have continued in bolting stuff on some of it like the folder interfaces and multithreading are pretty cool) but it really depends on what you're targeting.
In my opinion the major flaw of OOP is that it treats types as though they are an immutable aspect of data, whereas they are only views into it. Defining everything in a strict way —as OOP tends to enforce— can limit many errors and structure your programs, it only becomes a problem when it begins to limit what you can do. Sadly it often does —you can't iterate over that because it's creator didn't explicitly say you could!— and so people get tied up writing wrapper classes and endless boilerplate trying to convince the machine that the obvious is just that.



I feel that is important to note. Functional languages are inevitably unrepresentative of the underlying architecture, and while it may be possible for a JITer to optimize the program into something relatively efficient, the language ultimately hides the actual details of the computation and thus inhibits good algorithm choice. This is convenient for the purpose of solving problems in a seemingly sensible manner, but will inevitably lead to inefficiencies as the methods don't match the machinery.


I don't quite agree. I think it's better to learn the language first with an IDE handling the tooling for you, and then learn how the toolchain works. I agree it's essential to understand the tooling, however on the side of pragmatism, I think the complexity of the tooling contrasted with the triviality of their first programs will prove to be a turn off for many newcomers.

I do find it rather funny when functional people get all snobby about their beautiful languages; whose implementations are written in C anyway :story:
You'll never be free of us!
As for the IDE question (And this concerns you too @Yotsubaaa). IDEs are fine, I understand their purpose and for debugging it's much better than fiddling about with GDB. It's just that in my experience they've been a pain to deal with in certain cases. I've always found them to be a memory hog and as a guy who opens a million tabs, opening another webbrowser (Or Eclipse's Java application) to do my coding in slows my pc to a crawl. There's also the issue that Visual Studio is an absolute bastard when it comes to storage space. 15GB was my last installation although this isn't as bad as QT where the libs themselves are this size.
In essence it significantly hurt my ability to just flippantly open up a project to do some quick coding in the background instead of having to dedicate my full PC to working.
This was until I accidentally discovered gcc on a completely unrelated linux CLI administration course when I had finished my work and was bored.
 
I don't recommend starting with C++ —though it's very much worth learning, I'd start with something like C# or a scripting language. C++ gets quite complex, and a huge part of the initial learning curve is going to be the toolchain, so if you start with C++ you'll probably end up frustrated just wrangling the compiler and it's many components.

Once you've gotten the hang of common programming concepts, then I'd tackle C++. I personally started with python, and then moved to C++. I found that python —though it taught me an adequate amount of general programming— taught me very little about computers, while C++ taught me quite a bit and that knowledge has been applicable to every language I've encountered since.

Learning an abstract language is a good starting place, but it won't teach you anything about computers, and once you understand the principles of the underlying architecture you can make much better programming decisions.

Edit; also let me recommend C++ for dummies —no, I'm not joking— it's quite a good book to start with, and it's how I started. The best teacher is of course practice, but it's good to get your feet on the ground first.
The For Dummies books are great for learning anything. I've read the ones on Mormonism, Islam, and Calculus. I think their name, while catchy, puts people off of reading them because it sounds like it's shallow. They're not, they're just very tightly written.
 

PimpKramer

Poley the Polar Bear #1 fan
kiwifarms.net
As a newcomer, which languages should I learn first? I was thinking about learning C++, but it is a big language, and I don't know if I should start with something else before getting to learn C++.
I'll second the suggestion of either Go or Python. Both languages have a massive standard library containing libs you'd have to search for in a lower level language and relatively simple syntax allowing you to get building quicker. You'll learn a lot more just going to code something you want in one of these higher level languages than going through a huge theoretical book or something. I like Go a bit better because of static typing, compiler errors and being compiled but you can't go wrong with either.
 

Shoggoth

kiwifarms.net
Also functional programming is for people with broke brains and all assertions of "efficiency" are quashed by the unavoidable fact that all machines are imperative by nature.
I feel that is important to note. Functional languages are inevitably unrepresentative of the underlying architecture, and while it may be possible for a JITer to optimize the program into something relatively efficient, the language ultimately hides the actual details of the computation and thus inhibits good algorithm choice. This is convenient for the purpose of solving problems in a seemingly sensible manner, but will inevitably lead to inefficiencies as the methods don't match the machinery.
So unimaginative. The basic Moore machine can be written as follows:
Code:
state[t+1] = f(state[t], in[t])
out[t] = g(state[t], in[t])
Now I'll be damned is that shit isn't exactly the state monad. Moreover, if you look only at the state equation, it's recustive*, with the other variable being the next of an infinite, unknown in advance, series.
So enough of that. The main problem in using functional languages with machines isn't the imperative nature, but the fact that machines are place-oriented. C arrays are just pointers (places). Indexing is just taking an offset to another place. You can address registers. Places complect value with state(?).
Perhaps you'd like to talk to a SECD machine about a functional language when you have time.
Regarding the JIT, it's better than you think, take JVM JIT for example:
For large enough data sets / long enough living problems, the JIT can win over a compiled language. That's important to understand, and important to know how modern JITs and GCs work. They're quite good.
So every functional language written on the JVM and doesn't screw around too much with the underlying mechanisms will benefit from the same optimizations, yes?
Interestingly, the JVM happens to be a stack machine (SECD)
In my opinion the major flaw of OOP is that it treats types as though they are an immutable aspect of data, whereas they are only views into it. Defining everything in a strict way —as OOP tends to enforce— can limit many errors and structure your programs, it only becomes a problem when it begins to limit what you can do. Sadly it often does —you can't iterate over that because it's creator didn't explicitly say you could!— and so people get tied up writing wrapper classes and endless boilerplate trying to convince the machine that the obvious is just that.
The main flaw of OOP isn't data rigidity, and I hope other folks with OCaml experience can chime in on that one, but STATE. It's all about state. Objects complect state, identity and value. They tie behavior to state. They're a mess. Message passing is better and solves half the problems (smalltalk, erlang, akka), but immutability solves all of it.
Ya'll niggas got to read Out Of The Tar Pit
 
Last edited:

ConcernedAnon

Concerned and hopefully anonymous
kiwifarms.net
So unimaginative. The basic Moore machine can be written as follows:
Code:
state[t+1] = f(state[t], in[t])
out[t] = g(state[t], in[t])
Now I'll be damned is that shit isn't exactly the state monad. Moreover, if you look only at the state equation, it's recustive*, with the other variable being the next of an infinite, unknown in advance, series.
I'm well aware you can do this but I wasn't arguing that FP lacked ability, or even against most of the features of FP. I'd rather argue that this aversion to state is misplaced.
So enough of that. The main problem in using functional languages with machines isn't the imperative nature, but the fact that machines are place-oriented. C arrays are just pointers (places). Indexing is just taking an offset to another place. You can address registers. Places complect value with state(?).
Perhaps you'd like to talk to a SECD machine about a functional language when you have time.
Imperative implies stateful so I don't really get the point of the distinction you're making.
Regarding the JIT, it's better than you think, take JVM JIT for example:
For large enough data sets / long enough living problems, the JIT can win over a compiled language. That's important to understand, and important to know how modern JITs and GCs work. They're quite good.
So every functional language written on the JVM and doesn't screw around too much with the underlying mechanisms will benefit from the same optimizations, yes?
Interestingly, the JVM happens to be a stack machine (SECD)
I can certainly appreciate that fact, and I've even seen it in action. My current project in java (a game) has an interesting performance profile that improves steadily with time. However not even all of the JIT finesse in the world can solve GC stuttering, and so I'm forced to write things in an ugly fashion —object pooling gets quite tedious when you have to pool individual vectors. I expect the same would be true of any functional language on the JVM. If consistent framerates are not a goal though, you'll probably be fine.
The main flaw of OOP isn't data rigidity, and I hope other folks with OCaml experience can chime in on that one, but STATE. It's all about state. Objects complect state, identity and value. They tie behavior to state. They're a mess. Message passing is better and solves half the problems (smalltalk, erlang, akka), but immutability solves all of it.
Ya'll niggas got to read Out Of The Tar Pit
The issue remains that if you want to make a system that "appears" stateless you will necessarily need to hide the fact that the underlying architecture is in fact stateful. This abstraction almost certainly will not be free. In many cases it's probably simpler to just accept statefulness as a perhaps ugly, yet useful fact of computers. It can be wrangled with a little care and rigor.

—————————

All that talk yesterday of C++ and toolchains got me working on one of my projects again; an imperative language focused on reflection. Immediately I found my claim of "toolchain hard; start with IDE" to be validated. For whatever reason Clang, Ninja, and CMake don't play well on windows. First it was the resource compiler —which I don't even need atm— cmake refused to build without it, refused to find llvm-rc, and Ninja even refused to call it when I manually specified it. Reinstalling CMake fixed that, but llvm-rc then proceeded to refuse to find the test manifest generated by CMake, which required a reinstall of llvm + Clang. Even then CMake was unwilling to find the libs for targeting windows —and while I considered specifying them manually, I ultimately said fuck it and let msvc do the job
:stress:
Incidentally, reinstalling llvm is a pain because the inconsiderate people at llvm sign everything with pgp, and the only common windows program for verifying pgp is gpg4win which is 200 fucking megabytes. I literally just wanted a command line program to verify downloads. GOD. Turns out the best option was just to use WSL to run the linux version of GPG :story: If only they'd given a SHA hash for the windows binary 😩

After all this shit I was able to get some good work done though. I'm excited about it; it's intended to be a JITed language with a focus on reflection, and one of it's distinguishing features is the ability to retype objects, while also having a C-like object model. I know that's a strange set of features, but it's what I like. @Shoggoth Incidentally with regards to JIT, I'm intending the language to execute initially in an interpreted form while being steadily JITed over time, with the hope that data about usage can be collected during interpreted execution and used to guide the JIT. Of course that's a ways off, I'm just focusing on getting things working at a baseline.
 

cecograph

kiwifarms.net
Now I'll be damned is that shit isn't exactly the state monad.
You're looking pretty damned to me. Monad talk is seriously mathematically rigorous, so you'd need to be able to tell me at least where the functor is and where the unit and join are. I can do those for the state monad as it appears in Haskell, but unless you're a much better squinter than me, I can't see it here.

The main flaw of OOP isn't data rigidity, and I hope other folks with OCaml experience can chime in on that one, but STATE. It's all about state. Objects complect state, identity and value. They tie behavior to state. They're a mess. Message passing is better and solves half the problems (smalltalk, erlang, akka), but immutability solves all of it.
Ya'll niggas got to read Out Of The Tar Pit
I'm an Ocaml folk, but don't know how much I can chime in. Just about everything I've seen described as OOP I've found to dislike, but I've seen the term "OOP" applied to such wildly different systems that I can't point to any single thing that bothers me.

It's not the mutability. I use mutability (sparingly) even when not using objects. And Ocaml has an object system, but you can use it immutably.

What I dislike in statically typed languages is the fucking subtypes. This is the property of your type system where a value can have multiple static types, with the static types arranged in a lattice. It's the "is-a" relationship. A cat is a mammal, meaning that if you have a value that the type system judges to be of type cat, it should simultaneously judge it to be of type mammal.

I don't like this. It nearly always breaks global type inference, and it really complicates generics: in C# and Java, that complication appears as type bounds on generic parameters. In Ocaml, Kotlin and Scala, it appears as variance annotations. These are noisy and annoying. And it's not that I'm not smart enough to grok variance. I have to do that anyway whenever I think about functors (in the category theoretic sense), and there I notice that subtype variance is just the peculiar variance that comes when mapping and comapping inclusion functions (i.e. coercions).

And the touted benefits of subtyping seem to be things I get better elsewhere. The standard use cases of dynamic dispatch are better solved with sum types. And the standard use cases of late-binding are better solved with lambdas (objects are poor folks' closures).

Common Lisp is a different story, as is Smalltalk, where from the get-go the engineering is geared towards the programmer living in the same runtime image for years, continuously debugging and hotplugging it. That's a whole other level of mutability, but it's the reality of using a real system. In Common Lisp terms, it means that when I add a slot to a class definition in debugging, the right thing to happen is that all live instances of the class get told to reinitialize to the new class.

This isn't the wimpy world of Python. In fact, I don't know of any languages other than Common Lisp and Smalltalk that have any decent story like this, and if only OOP were identified exclusively with these languages, I probably wouldn't be so hostile to the concept.

My current project in java (a game) has an interesting performance profile that improves steadily with time. However not even all of the JIT finesse in the world can solve GC stuttering, and so I'm forced to write things in an ugly fashion —object pooling gets quite tedious when you have to pool individual vectors. I expect the same would be true of any functional language on the JVM. If consistent framerates are not a goal though, you'll probably be fine.
If you're writing a game in C++, you'll use object pools, and it's standard to only malloc between levels.

Java is horrible for games because it doesn't let you declare that your stuff belongs on the stack. You're relying on the JIT to figure out that your object lifetimes follow a stack discipline, and if it can't, you're writing code that is far far uglier than anything you'd write in C or C++.

C# has a better story.

But yeah, for high performance games, I always want to be using a systems language.
 
Last edited:

Shoggoth

kiwifarms.net
You're looking pretty damned to me. Monad talk is seriously mathematically rigorous, so you'd need to be able to tell me at least where the functor is and where the unit and join are. I can do those for the state monad as it appears in Haskell, but unless you're a much better squinter than me, I can't see it here.
Alright, squinting time
Taking for example the state monad from clojure's algo.monad:
Code:
(defmonad state-m
   "Monad describing stateful computations. The monadic values have the
    structure (fn [old-state] [result new-state])."
   [m-result  (fn m-result-state [v]
                (fn [s] [v s]))
    m-bind    (fn m-bind-state [mv f]
                (fn [s]
                  (let [[v ss] (mv s)]
                    ((f v) ss))))
   ])
Functor example from cats:
Code:
p/Functor
    (-fmap [_ f fv]
      (state (fn [s]
               (let [[v ns]  ((p/-extract fv) s)]
                   (d/pair (f v) ns)))))
with `state` being a state-monad constructor.
I accept that this is a bit of a squinty explanation, and maybe I sound like a madman, but I see it at this point, if you're still unsatisfied I can come back to it later today when I have more time.
quick edit: just to tie it back to a Moore machine, the state monad would be the register bank, and the functor would probably be the function / logic part

It's not the mutability. I use mutability (sparingly) even when not using objects. And Ocaml has an object system, but you can use it immutably.
Can't escape mutability, because we need to affect the world and not just heat up the cpu. What I'm aiming at is tightly controlled and well understood mutability vs. using it willy nilly all over the code. It's usually when mutability is involved that you can't reason about the state of your program and can't faithfully reproduce it, which is crucial for reasoning and for debugging. A program can also escape our understanding with "immutable state", like when adding an additional state argument to every function.
Java is horrible for games because it doesn't let you declare that your stuff belongs on the stack. You're relying on the JIT to figure out that your object lifetimes follow a stack discipline, and if it can't, you're writing code that is far far uglier than anything you'd write in C or C++.
afaik the jvm doesn't put anything but primitive values on the stack, everything else is a reference to the heap anyway. Whenever I tried to tune performance at that level my main concerns were creating objects which could be recycled, like a thread local string builder, reducing garbage, which goes hand in hand with the first, and reducing copies. It isn't that you can't get good performance out of the jvm, but even sans gc stop-the-world THE WORLD it's complicated to write and think about.
 
Last edited:
  • Informative
Reactions: Yotsubaaa

cecograph

kiwifarms.net
quick edit: just to tie it back to a Moore machine, the state monad would be the register bank, and the functor would probably be the function / logic part
Sorry for not being clear. That was the part I'm not seeing. The description of a Moore machine involves three fixed sets: an input set I, an output set O and a state set S, and two functions of type:

Code:
S x I -> S
S -> O
The state monad involves a state set S and maps a set A to the function space

Code:
S -> A x S
I don't see an exact fit here.

afaik the jvm doesn't put anything but primitive values on the stack, everything else is a reference to the heap anyway.
Exactly what happens depends on the compiler and VM, but Hotspot should be smart enough to realise when an instance can be allocated entirely on the stack. Ensuring it does so is then a game of tuning and profiling, whereas it's something you have much better guarantees about on .NET.
 

Citation Checking Project

I will not stop until I look awesome
True & Honest Fan
kiwifarms.net
Sorry for not being clear. That was the part I'm not seeing. The description of a Moore machine involves three fixed sets: an input set I, an output set O and a state set S, and two functions of type:

Code:
S x I -> S
S -> O
The state monad involves a state set S and maps a set A to the function space

Code:
S -> A x S
I don't see an exact fit here.
For the first one, take unit ∙ bind.
Given the curried type judgements
Code:
unit: a → M a
bind: M a → (a → M b) → M b
and with
Code:
M a ≡ S → a × S
We find
Code:
unit ∙ bind: a → (a → M b) → M b
unit ∙ bind: a → (a →  S → b × S) → S → b × S
Now let a be the input set I and b be the unit type denoted ()
Code:
unit ∙ bind: I → (I →  S → () × S) → S → () × S
which can be rearranged into identity on (S → I → S), which means that the Kleisli category of the State monad can be used to model your first type. This isn't surjective though, so there's no inverse mapping. Is that why you don't consider it an "exact fit" ?
As for the second one, we'll write an object in the same Kleisli category of type a → M b with a being unit and b being the output set O. The type becomes () → S → O × S. Once we obtain a O × S we can discard the second member to keep the O.
 
  • Informative
Reactions: Yotsubaaa

cecograph

kiwifarms.net
That looks pretty convoluted. Where's the (unit . bind) coming from? That's always just flipped application (of a Kleisli arrow).

If we're allowed Kleisli, then I just take arrows from I into M O, and with state I have

I → S → (O, S)

which is the type of Mealy machines.

But no, I wouldn't say this is exactly the state monad. It's exactly the Kleisli arrows of the state monad.
 
  • Informative
Reactions: Yotsubaaa

Citation Checking Project

I will not stop until I look awesome
True & Honest Fan
kiwifarms.net
That looks pretty convoluted. Where's the (unit . bind) coming from? That's always just flipped application (of a Kleisli arrow).
I wrote unit∙bind off intuition because I was looking for an expression of type S → I → S, then I rolled with it. It's not the most elegant thing ever but I didn't expect otherwise. Your solution is cleaner.

If we're allowed Kleisli, then I just take arrows from I into M O, and with state I have

I → S → (O, S)

which is the type of Mealy machines.

But no, I wouldn't say this is exactly the state monad. It's exactly the Kleisli arrows of the state monad.
Why would we not be allowed Kleisli?
Moore machines are a special case of Mealy machines. Here we go: we showed the link between Moore machines and the state monad.
 
  • Informative
Reactions: Yotsubaaa

Shoggoth

kiwifarms.net
Oh, I'm not disputing we can find a link (and we have). But Mealy machines aren't exactly Moore machines, and the state monad isn't exactly the Kleisli arrows over the state monad.
Ah, actually a Mealy machine would be a better model for it now that I look at the formal definitions, but aren't Moore and Mealy machines functionally equivalent, i.e. one could be used to model the other?
 
  • Informative
Reactions: Yotsubaaa

ConcernedAnon

Concerned and hopefully anonymous
kiwifarms.net
I don't speak wingding you fucking niggernerds, ←↭↰↻↠↞↘↜↡↹ right back at you

If you're writing a game in C++, you'll use object pools, and it's standard to only malloc between levels.
Certainly, I just find the fact that Java necessitates the pooling of goddamned 3-vectors absurd and hilarious. Means I have to write all my vector math in an imperative style though, which is awful and confusing. Oh lord the horrors of writing game physics in Java
Java is horrible for games because it doesn't let you declare that your stuff belongs on the stack. You're relying on the JIT to figure out that your object lifetimes follow a stack discipline, and if it can't, you're writing code that is far far uglier than anything you'd write in C or C++.

C# has a better story.
Indeed it is, but Java is what the project started in, and I don't feel like starting over in C# this far into it. At this point the major GC allocations are for iterators and other small shortlived wrapper objects. Honestly it's far easier to just use thread-locals for vectors, which is fine so long as your functions aren't re-entrant. Really frustrating to not be able to just declare a vector type that'll sit on the stack though.
It is kind of funny though, the project was started by another guy and by this point none of his code remains because he had no idea what he was doing. I might as well have just started from scratch in C# anyway! Oh well.


I'm realizing more and more that I basically want HolyC with managed memory and an interface system
My stab at it has been going relatively well; right now I'm working on a bytecode format to store programs. One problem I haven't quite settled on a solution for is how to represent s-expressions in a bytecode format. My current thinking is to create nested expressions based on data dependencies.
For example here's pseudocode for a function that calculates the number of distinct combinations of n objects —(n * (n - 1)) / 2;
Code:
declfun $combs      # declare the function
declfunargs $0
declfunresult $result
deffun $combs        # define the function
sub $0, 1, $2
mul $0, $2, $3
div $3, 2, $result
endfun $combs      # function definition ended
Turns into this expression;
Code:
square = fun(_var0, result,    # lambda declaring argument 0, and a result
    return(result,
        div(
            mul(_var0,
                sub(_var0, 1)),           # (_var0 * (_var0 - 1)) / 2
        2))
)
Due to a desire to have interrogable and transformable expressions the bytecode isn't intended to be executed directly by the interpreter, rather transformed into objects that implement a function interface.

Anyone here have a better idea for representing s-expressions in bytecode? This'll do, but I feel it's not optimal.
 

Yotsubaaa

Yeahhh 2020!!
True & Honest Fan
kiwifarms.net
I don't speak wingding you fucking niggernerds, ←↭↰↻↠↞↘↜↡↹ right back at you
monads.png


jk @cecograph, @Shoggoth and @Citation Checking Project. I'm actually learning a lot about category theory as I'm (sort of?) following along with your discussion. I've always been meaning to take a look at Haskell and monads and everything, but just never got around to it for whatever reason.
 
Tags
None

About Us

The Kiwi Farms is about eccentric individuals and communities on the Internet. We call them lolcows because they can be milked for amusement or laughs. Our community is bizarrely diverse and spectators are encouraged to join the discussion.

We do not place intrusive ads, host malware, sell data, or run crypto miners with your browser. If you experience these things, you have a virus. If your malware system says otherwise, it is faulty.

Supporting the Forum

How to Help

The Kiwi Farms is constantly attacked by insane people and very expensive to run. It would not be here without community support.

BTC: 1DgS5RfHw7xA82Yxa5BtgZL65ngwSk6bmm
ETH: 0xc1071c60Ae27C8CC3c834E11289205f8F9C78CA5
BAT: 0xc1071c60Ae27C8CC3c834E11289205f8F9C78CA5
LTC: LSZsFCLUreXAZ9oyc9JRUiRwbhkLCsFi4q
XMR: 438fUMciiahbYemDyww6afT1atgqK3tSTX25SEmYknpmenTR6wvXDMeco1ThX2E8gBQgm9eKd1KAtEQvKzNMFrmjJJpiino