smosher_
return fself(num - 1) + fself(num - 2);
instead of calling fib (or fib_gen) explicitly. fself is passed into the generator and it will need to be passed in again and again. That's what Y gets you. You could get tracing the way you suggest from something like: let fib f n =
let n' = (* compute fib for n *) in
f n'
and supply some f that will log (and return) the computed values, but that won't work with the motivating example: memoization. This really should have been clearer in TFA.It's worth noting the memoization in the linked gist isn't pure. memo() allocates a cache and returns a function that references it. The cache is updated by mutating in place. After all the hoops we've jumped thorugh it's a bit of a let-down to end up here. (It's doable though.)
(Edit: improve clarity.)
I was trying hard to have a conversation while avoiding arguing about semantics, so thanks for that.
Either you think this way because of a sense of orthodoxy or because you think memory safety is important in a way the other kinds of safety aren't. I disagree, especially since "memory safety" may or may not imply protection against aliasing of mutable data. Those nuances I like about Rust probably wouldn't exist without the broader scope of safety concerns.
> As for voicing my objections to the Rust community,
About the discussion you linked? I meant to me, in the service of explaining your objections.
> My time is already quite filled following the JVM, .NET and C++ eco-systems, the ones I get payed to be an expert on.
Well, that was important information. Thanks for making the time to share!
That doesn't sound like abuse to me, as long as the exposed interface remains safe.
> some Rust devs are using it for anything they assume isn't logical safe.
That sounds like an objection to the scope of what Rust defines as safe. Unless you mean to imply there are reasonable, Rust-safe ways to rewrite the transgressions. In the former case I have to disagree. It would be nice if we could prove more. But you can't prove everything.
I haven't seen the ICFP talk but I might watch it later if you can link to a video. I've skimmed that discussion before but you will need to point out your objections—IMO it is great that Rust devs are having that discussion.
That's just it. Rust looks enough like C++ to catch on. This was not an accident though I can't say I'm jazzed about it.
Rust brings a lot to the table with its type system too. I would rather be using Rust tomorrow than having had the benefits of say Pascal derivatives for the past 45 years. I'm not saying this just for effect: after the obvious ML influence, the parts of Rust I like most are the nuances.
> Instead, many Rust users seem to sprinkle it everywhere.
Is that true? You will necessarily see it in bindings, or to implement certain essential features that can't be implemented otherwise. Beyond that there is the motivation to use unsafe code for speed, hopefully this is mostly restricted to modules.
Are you complaining that people are using when they could reasonably avoid it or that it is too often necessary?
Specialize to reuse (inheritance-like patterns in Rust)
I think that mentality, which I supported, may be what ruined green threads for Rust. Perhaps the enemy was the perfect of the good. On the other hand, maybe not having to worry about differences is the better benefit. I would rather be slower-but-acceptably-fast than have to think about 1:1 vs M:N threading in the case that they are not interchangeable.
On the third hand, it could be that Rust is too close to the metal for green threads to be of any significant benefit. If that's the case, Rust ought to trounce all the M:N implementations, subject to reasonable limits on spawn rate, memory pressure and inter-thread communication. Does that sound right?
Incidentally, I've never seen a cooperative threading implementation that didn't have a yield call of some kind available, and you can usually jam any of them up by writing an infinite computation-only loop, so even in the langauges where the scheduler is automatically invoked, correct 1:1 code can deadlock in the M:N scenario. State machines can too, but a trivial example, translated, might read something like the following:
for(;;);
exit(EXIT_SUCCESS);
I've seen code like this written by complete newbies, but threading constructs can hide that relationship even from experts. In parallel code it isn't a sequential relationship, but it is with cooperative threads. I guess this is all fairly pedantic (such a minor detail, mostly affecting only poorly-written programs), but in the end, one of: yield(), sched(), sync(), etc. does show up in practically all of the cooperative threading interfaces.If people start bypassing the DOM with canvas we will have a bigger problem than cosmetic filters failing: we will no longer be served the same kind of document. Or we will, but the content will be in an opaque region of it. If that happens the web is dead. People tried this before with flash and that smoldered for a while in the 90s but didn't last, so I'm not feeling all doom-and-gloom about it.
Aside: Standardized document formats are important. If rendering to canvas takes on as the defacto standard, it would cripple the web technologically.
I find constructing programs mathematically makes life easier in the common case and possible in nearly all others, unless you insist on things like proof-of-termination for programs which do not (I do not.)
1. 'best' because it gives us the means to reason about the code, and we know what kind of transformations we can perform on it, and do them abstractly without having to simulate it, potentially for infinite inputs, etc., etc. You know the drill.
> and frankly I don't understand why mathematicians want to take over a completely different domain
I would like to challenge the assumption here: that programming (in whatever mode) can't be adequately described by mathematics. I don't have time to make a thorough argument, but consider this: instead of thinking of what programming would be like as some kind of math, think of what math would need to be like to adequately describe your favourite mode of programming. (Forget arithmetic, consider algebra, geometry.)
As for FP: these days it wants all the tools, and it is picking up whatever it can formalize. Some FP tools are uncommon or don't work well outside the paradigm. To me that makes all the difference: I'd feel more restricted working without FP than by being strictly within it.
More exotic languages, which take the uninitiated longer to acclimate to, don't seem to be trying to tell people they're not allowed to think deeper about and question the design of the language. Good criticisms of Go were made on day 1 and are being made to this day, Rob Pike's ego notwithstanding.
At the end of the day, if I see a problem with a developing language I am interested in, I'm going to report it. If I'm met with: "I don't know you but I'll assume you don't know what you're talking about" that's a second problem and I'm not about to double-down on it.
There are details on getting the trace graphed in the tutorial. (If you want more detail in the trace you can uncomment the code on this line: https://github.com/chrisamaphone/interactive-lp/blob/master/... )
See also the github repo: https://github.com/chrisamaphone/interactive-lp/
There is an emphasis on using Ceptre for developing interactive fiction¹ (text adventures/parser games.) From my perspective, a pain point in developing truly creative interactive fiction is the tools available tend to impose a world model on your work. I'm excited for Ceptre because it lets you write causal relationships directly and that makes starting from scratch a more realistic proposition.
1. With some work I think it could be (and should be) used in other kinds of games, such as sandbox games or anything that would benefit from a living world, even if only in part if the main story must be nailed down and deterministic.
The concrete contribution of the research report here
is the design and implementation of a fully compartmen-
talized operating system, MINIX 3. To properly isolate
faults, we have removed all drivers from the kernel and
run them as separate, unprivileged user-mode processes,
protected by the MMU hardware. Since all servers also
run in user mode in our design, only a tiny microker-
nel that does not contain any foreign, untrusted code is
left in kernel mode. Each component has only the mini-
mum privileges it needs in order to prevent failures from
spreading. In our design, driver failures are no longer
fatal and do not require rebooting the computer. let _ = print_string "foo"
let _ = print_string "bar"
at the top level.Of course you can write
let msg = "foo" in print_string msg
let msg = "bar" in print_string msg
(which isn't at issue, except no semicolons are needed.)But you can't write
print_string "foo"
print_string "bar"
without semicolons.The reason this technique is called "beat detection" is it can be used to collect the individual beats from the stream contrasted with knowing the just the tempo doesn't tell you where the beats are exactly (and doesn't help a lick with finding the off-beats.) Tempo detection is only one product of these algorithms, and guesses can be constructed from any of them, though sometimes additional heuristics are needed.
The accuracy of the LPF technique is well worth criticizing. Yes, it's fairly good, but it's not the best one we have and the article says part 2 will describe a better technique. I should note that even organs and vocals can create transients that are often associated with beats. The LPF probably does better simply by eliminating false-positives.
It's expensive but well worth it for the people who click with it. I would recommend trying one before you buy it, especially if you can spend a good amount of time with it. I felt a little let down during my first week or so with it, but then it clicked and became instantly essential. It doesn't go that way for everyone, but it seems most people end up loving it.
I find gear lists distasteful so I won't go into much detail about most things, but I will give you an idea of what I have going on.
The thing I mentioned in the post is the OP-1: https://www.teenageengineering.com/products/op-1 (built-in synths, samplers, mic, radio, 4-track, sequencers...) It's my workhorse.
I like sampling, so there's a turntable and cassette deck. I like sampling a lot, so I'm getting another sampler.
I also have a subsynth to cover the areas the OP-1 synths don't. (They're very good, but each is specialized and has only 4 or 8 parameters.)
I also use a cheap (but not noisy) DJ mixer since I only need to mix two channels, and doing cuts with the crossfader when sampling is handy. The rest of it is cables, speakers, headphones and a few things I never use.
The sound is incredibly hard to get right in some cases. You can simulate vinyl remarkably well with a timecode record or DJ controller and special software, but: the plugins have extremely limited range compared to the real thing and the controllers require the same investment as a turntable and timecode still needs the turntable. Nearly every used record store and thrift store has a pile of nearly-free records which are ideal for sampling: obscure stuff no one has heard of, ancient stuff that is no longer recognized by today's audience or may have even been obscure in its day.
As for preferring hardware, in my opinion it's the responsible thing to do. Because:
* Say you want to play a show. Are you going to bring a laptop in there and pray it doesn't do something insane, say... auto-discover the wifi, start installing updates during your gig? Or just crash because it has an undiscovered cooling problem an it's hotter than your usual environment with all those bodies dancing around?
* Software tends to cost money too. There are free options, but chances are you will want _something_ in your software setup that isn't free.
* Idiosyncrasies. Just like your audience wants to hear that vinyl sound, producers often want those hardware quirks. A lot of this amounts to fetishism, but sometimes there are more objective reasons.
* Dedicated functionality. Portable instruments. Playable instruments. Jamming on a PC keyboard does not give you the same response as jamming on instrument keys or pads, or whatever the instrument has that is designed to be played. You could buy a controller, but then you're back to buying hardware.
* Workflow is king. Nearly everything software needs a mouse these days. Or a dedicated hardware controller. It's a workflow-killer.
I learned the hard way that I can't produce very well with software. A few years ago I went with a nice portable piece of kit that does a little bit of everything from sampling to synthesis and mixing. When I did that everything changed drastically. I thought about music differently and really started to get my hands on it.
Hardware isn't that costly unless you need to have the most badass kit or a large setup. When my wish-list is complete, mine will have cost me about $1500. A decent laptop + Ableton Live + midi controller would be cost at least that much. That will take you far, but it's not an argument against just buying the hardware instead. Some people work better with software, and that's cool, but for anyone who works better with hardware, the word "preference" only works in the sense that "I would prefer not to have my hand chopped off." It probably goes both ways, but I couldn't tell you about that. ;)
Around 2:10 he mentions "you can actually set it for project as well" which is a lot closer to what's being done in this case.
Blender has to solve nearly the exact same problem for projections, the only differences being the projection has to be mapped backwards to a flat texture, and you have to account for the way the film clings to the surface and how it stretches. Topology and topography aren't an issue though, we've got that so covered. (But the material physics is something you would have to construct a model for, so if you wanted to solve this precise problem in Blender you might have better results with the physics engine.)
I have seen some variation on this available in even low-end 3D modelers since the 90s. IIRC Truespace's version of the feature did shrink-wrapping by running a simulation, much like they do here, but with different physics.
I thought I had even seen this used in printing before but I could be mistaken.
Bonus the-future-is-now moment: "3D vision systems" are "off-the-shelf components".