It's a bit disappointing that a relatively new language like Rust doesn't handle these correctly.
There's no value in a String type if it doesn't behave for text. One can simply use a "Array<char>" to convey proper semantic meaning.
HN user
mortoray.com
It's a bit disappointing that a relatively new language like Rust doesn't handle these correctly.
There's no value in a String type if it doesn't behave for text. One can simply use a "Array<char>" to convey proper semantic meaning.
It's not about reversing, but about checking whether reverse iteration works. This is required to perform proper truncation (for limited length fields) as well as visual editing for a cursor to go through the text.
It can additionally be an indication as to whether regular expression matching works, though that is usually handled by a library, and not the core string types.
My contention was always that if a "string" does not reverse text, then it's no better than an "array<char>". The existence of a "string" type implies it should do more.
It'll probably help in this case since I suspect it's computational overhead introducing the bottleneck, nothing architectural.
Alas, I might have to wait, as I tend to use Python 3.8 and it's not supported yet -- though mainly I use it for types, it might actually run in 3.7
I intend on adding WebRTC as a channel for higher volume discarble messages, such as the cursor position of all players.
I agree. General purpose pattern matching in both expressions and function dispatch is a great feature.
Great!
I do not have a good reason. A lot of my recent stuff isn't technical, so it's only on the Medium pages. I guess I tend to post those links often now.
I chose LLVM from the start since I knew some of the challenges that interested me couldn't be done at the C level -- or rather it'd be more complicated at that level than at the LLVM level.
Thank you.
When I started Leaf it was to scratch an itch. It was really only when the motivation dropped that I tried to find ways to use it, to renew my interest in pursuing it.
Perhaps that did not come across in the article well. When I set out to do Leaf that was the goal of the work. It's wasn't a diversion to some other goals. Over time my priorities changed, and I was trying to force myself to follow Leaf to follow them.
Had I wanted to make a game from the start I would most certainly not have made a language first! That would be crazy. And that's my comments about sunk costs -- just because I have Leaf, it'd still be crazy to do this other projects in it.
I, the author, am tending to agree now. :)
Okay, they are classified but I don't see that anything in the setup, or pip package management, seem to actually use them. Are they somehow used in actual package management, or just search qualifiers?
That is not an actual migration guide. It's merely a meta-doc saying what types of things you need to pay attention to. I was looking for a specific list of things that would have to be migrated. The docs mention of reading the release notes for each versino of Python 3 isn't very helpful.
The `iter` form of the `readline` doesn't load the entire stream first, whereas the second form you posted does. This makes a significant difference when reading data from another program.
I saw that migration guide, but it has very few details about what is actually involved in migration. It doesn't include API change details.
The simple syntax changes I did prior to running 2to3 as they came up on the first run I tried. The semantic changes that didn't come up in 2to3 is what I was more bothered about.
#1 has a big influence on my argument. I think it was Python and NodeJS library systems that made it super simple for people to publish libraries. There are a lot of trivial libraries out there, and many of questionable quality. Sometimes using a library ends up as more work than writing the bits of code myself.
It's not like I'm going to decide to write a new 20k line library for my project, but if something is only a few hundred lines of code it's definitely easier to just rewrite.
I (the author) can certainly do the silly algorithm tests, but whether I can contain my snide remarks enough to get the job is uncertain. :)
Those are some of the points I'm considering as well when doing the memory management for Leaf. My desire to have predictable destructors is tough to reconcile in a tracing GC.
I'm uncertain of what you mean with "copying the data over" in reference to large data. Surely it's still just the pointer being copied? Or are you speaking of things like `std::vector` in C++ that are value-copied by default?
In my quest for a memory management scheme on Leaf it's your final point which is primarily forcing my decision: the compatibility with other memory managers. In this article I just wish to provide counterpoint to those people trying to convince me that tracing GC is a better approach. In the end, it's the need to right libraries and be compatible that prevents me from using a complex GC.
In my conclusion I mention why there are no benchmarks, it's nearly impossible to construct a realistic comparison between the two techniques.
When I cosnider tracing GC my primary arguments against it have nothing to do with performance at all, yet it often comes up as an argument against my position. This article is attempting to address that critique, by saying I doubt you could compare the two directly.
I'm not sure how this disputes what I say about a scanning garbage collector. The number of live objects is proportional to the amount of total memory allocated.
I don't consider dead objects, where the memory is not longer used and free to be allocated, to be part of the allocated memory.
I (author) actually agree that reference counting is a form of garbage collection. However, in most dicussions about memory management the generic term garbage collection tends to refer to scanning collectors. In particualr, people who often oppose my views on scanning GCs are the ones that actually use the term garbage collector to refer to those types of collectors.
Most places I see talking about reference counting just say reference counting, sometimes mentioning memory management. Automatic memory management is perhaps the most generic term.
How reference counting actually works is covered in my previous article, which I wrote as a lead-up to this one. It covers the particulars of how memroy coherency is the primary cost of reference counting.
Yes, round is usually a safer choice, but in this case we had reasons to use floor and ceil, and thus had to deal with the issue.
I've added a section to the article with a more correct snapping function showing the issue more clearly (I hope).
Rounding to the nearest value does avoid the problem I had in the article. But we really wanted to `ceil` in this case, to guarantee an element is never smaller than a provided value (and doesn't end up as 0 size).
Python actually seems to show a much higher precision than other languages (higher than C's printf default I belive).
Interesting is that print can show an exact representation of any floating point value, but of course 0.1 can't be represented exactly.
I agree my initial examples were not clear enough to illustrate the problem precisely. I've added a section now about idempotance and how this slight varation in floating point is causing my original problem.
Your point about floating point not having exact values is precisely the issue, and that is what my added example tries to demonstrate. My previous article, linked from the intro, about floating point tries to cover that aspect a bit more.
http://mortoray.com/2015/07/06/essential-facts-about-floatin...
This is the "correct" behaviour of `floor` obviously, but the unexpected part has to do with floating point accuracy and use domains.
Numbers will end up slightly lower or higher than an expected value simply due to accuracy in calculations and minor differences in input.
For example, suppose we have two UI elements, one with a width of 80% and the other expressed as a factor as 0.8. Depending on how specifically these are parsed and processed this may result in slightly different values. For the user creating the UI however they'd expect the same result.
The epsilons I introduce into my floor/ceil code is meant to deal with these minor variations.
I suppose in hindsight my example doesn't look as disturbing as it's meant to. :)
It's hard to show concise examples that truly show how this little bit of error eventually compounds and destabilizes a calculation.
I'm not sure 80-bit floats are a thing of the past. Many calculations still benefit from the extended precision compared to 64-bit. The issue also crops up agian on some platforms that can do 128-bit float, but are then truncated down to 64-bits for storage.
I agree there are ways to avoid that problem, but the general issue of truncation across storage/calculation I think remains an important concept.