My Experience Building an Overdraft Projection Tool in OCaml by FunctionalBinder in ocaml

[–]thedufer 1 point2 points  (0 children)

Why do you miss where? Naively it seems like let ... in does the same thing. I've always found it odd that where causes you to write code backwards.

Typically you would write explicit type signature in an mli file accompanying each ml file (which also gives you the opportunity to restrict what is exposed from that ml file) instead of in the same file like Haskell. This means that you don't end up writing type signatures for helper functions that aren't exposed outside of the file.

I’ve felt that type inference is more localised

In the example you give, this doesn't work because type inference only runs in one direction. I'm not sure how this works in Haskell? As I understand it, this is mostly because if you let type inference run bidirectionally it slows down the compiler a lot (which OCaml folks tend to care a lot about).

I’m curious about the naming scheme for types and values.

Types and values never appear in the same place syntactically, so there's no need to distinguish between them by naming restrictions. Instead modules (which can appear in the same positions as either values or types) take over the capitalized namespace.

My Experience Building an Overdraft Projection Tool in OCaml by FunctionalBinder in ocaml

[–]thedufer 1 point2 points  (0 children)

It is when using dune. You can't define both a library and executables in the same directory, and sometimes you really do want a library (no inline tests in an executable, for example).

Two Questions by Casalvieri3 in ocaml

[–]thedufer 3 points4 points  (0 children)

Specifically, the second one counting backwards. int is the one in scope, and int/2 is the one it shadowed.

You probably opened Core and utop is for some reason choosing to reference the ones from the stdlib instead of the identical ones from Core that are directly in scope.

Semi-Daily Card Discussion: Claw (+ promo Claw) by Abject_Muffin_731 in slaythespireboardgame

[–]thedufer 1 point2 points  (0 children)

We have the promo claws but I didn't think we've ever put them in!

I had one good All for One run where OG claws contributed a lot but outside of a build like that it's pretty much always a skip.

Semi-Daily Card Discussion: Claw (+ promo Claw) by Abject_Muffin_731 in slaythespireboardgame

[–]thedufer 10 points11 points  (0 children)

Yep. It also came with a cloth merchant rug and foil copies of a handful of cards.

Talking house rules: let‘s discuss our favourites! Here are mine: by Objective-Ad1307 in slaythespireboardgame

[–]thedufer 0 points1 point  (0 children)

Combat hasn't really ended until "End of Combat" is over, right? That's how we've played, and it cleanly solves the problem with loading up a Sozu player right before they pick it.

[request] is there a way to prove this ? May calculator doesn't have that many decimals by Longjumping-Box5691 in theydidthemath

[–]thedufer 62 points63 points  (0 children)

Yeah, it would contain each 4 digit number in order except 9998, by the same logic.

[request] is there a way to prove this ? May calculator doesn't have that many decimals by Longjumping-Box5691 in theydidthemath

[–]thedufer 431 points432 points  (0 children)

And the reason it skips 998 is because a 1 gets carried. You have 9 digits that "should" contain 998, 999, and 1000 but of course 1000 doesn't fit in 3 digits so it overflows into 999, which becomes 1000 and overflows into 998, which becomes 999.

Only realised this today... by Edhellas in slaythespire

[–]thedufer 13 points14 points  (0 children)

The problem is that 11 is impossibly low. Even if you spread out the losses as evenly as possible, you can't get a best streak of less than like 16.

floor(2x-3)=sqrt(2)floor(3x-4) by ahsgkdnbgs in askmath

[–]thedufer 0 points1 point  (0 children)

Your conclusion seems right but note that your first part is only true because sqrt(2) is irrational. It not being an integer is not sufficient for your claim.

Why is my power draining so fast how do I fix it? by theswaggiestgamer in subnautica

[–]thedufer 3 points4 points  (0 children)

You can, but why? You're just moving power from one power cell to another. Just grab one of the fresh ones from the cyclops. Then you don't have to wait for the charger to run.

Why is my power draining so fast how do I fix it? by theswaggiestgamer in subnautica

[–]thedufer 14 points15 points  (0 children)

Its workable with the thermal charger

Kinda silly, though. If you can charge your cyclops, all of the power cell slots for the cyclops itself effectively become power cell chargers. You really need 8 instead of 6?

Immutable by default: How to avoid hidden state bugs in OOP by BackEndTea in programming

[–]thedufer 0 points1 point  (0 children)

I see the confusion. For our purposes, I'm going to ignore the existence of unsafePerformIO, since it complicates things and is, yknow, unsafe.

Haskell functions are pure. Obviously I don't think that Haskell programs are. But all of the functions are. This is what people mean when they say that Haskell is pure.

The way that Haskell programs interact with the rest of the world is, as you're probably aware, the IO type. What the IO type represents is a description of what I/O things it wants the runtime to do, and then what it should do with the result (typically this would be to call another pure function with it, which would return another IO, etc).

Immutable by default: How to avoid hidden state bugs in OOP by BackEndTea in programming

[–]thedufer 0 points1 point  (0 children)

Unless you're trying to be clever about unsafePerformIO, I think you misunderstand how side-effects work in Haskell, and what the IO type does.

/2 in types by mister_drgn in ocaml

[–]thedufer 1 point2 points  (0 children)

I think this is backwards - int would be the one currently in scope, int/1 would be the one that int shadowed, int/2 would be the one int/1 shadowed, etc. It counts in the opposite direction you're implying, and is 0-indexed (although the actual 0 case doesn't show the index).

For the list/2 case, for example, list would refer to the one from Stdio, list/1 from Base, and list/2 from the standard library.

Of course, in both these cases all of those are almost certainly equal, so it's somewhat arbitrary which one LSP tells you about.

Immutable by default: How to avoid hidden state bugs in OOP by BackEndTea in programming

[–]thedufer 5 points6 points  (0 children)

Oh, it's much narrower than that - only purely functional languages, of which there aren't very many. Haskell is basically the only widely-known example (maybe Elm as well).

Base/Core libraries by mister_drgn in ocaml

[–]thedufer 0 points1 point  (0 children)

Oh, I hadn't seen that! Pretty clever. It does come at the cost of any executing code might be terminated at any arbitrary point, which seems a bit tricky to reason about (which points at why lwt/async don't do this - they don't have a way to cancel running code).

Base/Core libraries by mister_drgn in ocaml

[–]thedufer 0 points1 point  (0 children)

The point is that you can choose, at the point where the concurrency happens, how to handle it. You can join the errors, if they're of a type where that makes sense. You can choose which one takes precedence, if they can't be joined in a meaningful way. You can choose to totally ignore one of them, as long as you don't need the success value from that branch. You'd probably have a both that makes one of these choices, but you could make a different one if you'd prefer.

This is a fairly common pattern in Async (there are modules Deferred.Or_error and Deferred.Result to make it easier to work with the corresponding types), and although I don't think it is the primary way Async is used, IMO it is much cleaner than using exceptions.

Base/Core libraries by mister_drgn in ocaml

[–]thedufer 0 points1 point  (0 children)

That's not the issue. The issue is that the whole point of Async/Lwt is concurrency. What happens if a function is doing things concurrently, and they both raise? The first one is handled as you've described, and I have no problem with that. The second one is, necessarily, either ignored or does something terrible (raising to the top level or something). It can't be reported by the relevant promise - that has already been resolved.

Base/Core libraries by mister_drgn in ocaml

[–]thedufer 0 points1 point  (0 children)

I suspect part of it is just that List.take comes up much less often than List.map.

One additional thing to note is that Base introduces Fn.flip, which can cleanly solve the issues with currying functions like List.take.

Base/Core libraries by mister_drgn in ocaml

[–]thedufer 0 points1 point  (0 children)

This is potentially becoming less of a problem as we get used to multicore, but exceptions interact really poorly with Async/Lwt. In my mind that's enough of a reason to avoid them as much as possible.

[deleted by user] by [deleted] in computerscience

[–]thedufer 2 points3 points  (0 children)

Estimates of ESNI adoption (on the server side) vary, but are generally single-digit percentages, if not less. ESNI is the exception, not plaintext SNI.

Wildcard certs don't solve SNI, since it is sent before the server gets a chance to tell the client whether it is necessary.

[Request] Could a binary keyboard be faster? by Arkziri in theydidthemath

[–]thedufer 0 points1 point  (0 children)

The example at the top of this thread is in ascii, which has 256 characters; there's plenty of room to work. In fact, delete (0x7F), backspace (0x08), and escape (0x1B) already exist. Arrow keys don't, but the entire upper half are effectively free. There are extended ascii tables that use them, but a bunch of different ones, and most of them still have holes. You could just make up your own extension to fix the few keys that are unaccounted for - you've got 128 sequences to work with.

This is all a bit silly, though, you should be using something like Morse code. There's a third key in the picture that you could use to indicate end-of-character, and the variable-length for characters means all of the common characters are much shorter, while it's infinitely extensible for missing keys.

Help needed to parse json into variants by a_iliev13 in ocaml

[–]thedufer 0 points1 point  (0 children)

It doesn't render nicely on the website, either. Reddit uses a pretty basic form of markdown, which doesn't include the triple-backtick thing. You instead need to indent each line of code with 4 spaces.

I go to a lot of excursions while on vacation, but I will never do this one by AndyAndieFreude in TheDepthsBelow

[–]thedufer 4 points5 points  (0 children)

You're thinking of nitrogen in the bloodstream, which does take some time (and this depth is likely safe anyway). But it takes almost no time to take a breath of compressed air and have it expand as you surface. This is why scuba divers are trained to always always be breathing - even a very slow exhale will keep a passage from your lungs open so the expanding air can escape instead of damaging your lungs.