12 ms·
Lessons learned from implementing a text editor related to front-end development
- mmjaa 9y agoThe more I read, the more I felt that the author was long-windedly discovering FSM's, only describing them using the language de-jour - i.e. JavaScript-ecosystem-ism's. Is this the state of things today - that kids start off as highfalutin' "developers", whereby 95% of their apps are written by others (because: "npm -i <all the things>"), and then .. eventually, from the top-down, trickle through the stack learning "the things", giving it all a new fancy name, and blogging about it? Because to me, this seems more like devolution at work in the computer science industries, not some kind of radically derived insight. I'm not trying to be overly critical, but for a lot of us, "discovering that C-based apps are, weirdly, similar to what us React-ites are doing" sure seems like a step backwards from real stack competency.
- keyle 9y agoIt's true that today's devs are glorified plumbers. On the other hand, so much gets done, it would be insane to go back to "C for all the things!". It's a trade off, you're either a high level hacker, piping stuff together and watching for leaks, or your a low level system guy, squeezing the carpet.
- nigifabio 9y agoI will state the opposite: It's a trade off, you're either cut and paste blue collar programmer, piping stuff together and watching for leaks, or your a hacker/engineer guy, doing CS.
- mmjaa 9y agoI would argue that a lot more of the worlds productive plumbing depends on C-based apps/libraries/frameworks than we would care to admit - its just that its 'not sexy' enough for the young-uns to get behind and start using, since everyone knows that C is a greybeard language and, therefore, not cool. The same argument ("so much gets done") was made for Visual Basic back in the day, you know. Oh, how the hoipolloi cried and crowed for the death of C developers back then. Oh, how they were wrong, oh so wrong! I'm not saying the world doesn't have a debt to pay to the Node/Javascript camp - it surely does. I just feel that there is something really missing in the scene, if in fact things that C developers knew and applied well 'back in the day' are just now being re-discovered as "Cool New Shit™" by those who chose - willingly - to ignore the very mechanics of the components their stacks are highly dependent on. Still, I guess its not worth complaining. Its good to know that JS guys can get over the wall, and discover that we've all been using state machines for decades now, and so on, eventually. I just wish there was a lot less hubris on the "crowing about it" side of things. Honestly, JS guys: you should know a little C. Its still there, underneath all the cool shit, and you're still heavily, heavily dependent on it, no matter what your "npm up" tells you...
- coldtea 9y ago>The same argument ("so much gets done") was made for Visual Basic back in the day, you know. And it was right, to the argument is moot. VB was a very productive language. Any issues where with the ecosystem moving on, not with VB (which had its warts, but all languages do, C first of all). >Oh, how the hoipolloi cried and crowed for the death of C developers back then. Oh, how they were wrong, oh so wrong! Again, they were right, oh so right. We do 1000x the programming we did in 1980 and 1990, but we don't use 1000x more C programmers (or assembly or pascal, two other popular choices at the time). Tons of code that used to be that, is now written in higher level languages.
- pjmlp 9y ago> Oh, how the hoipolloi cried and crowed for the death of C developers back then. Oh, how they were wrong, oh so wrong! Which is kind of true for us on Windows. Most of the C has been replaced by C++, to the point that even the new C runtime library is actually written in C++ with extern "C" entry points. Also for those of us on Android, where using the NDK is an exercise in patience writing JNI boilerplate, because Google doesn't want us using it more than strictly necessary. Oh and the two most beloved open source C compilers (gcc and clang) are actually written in C++. Now I admit that on traditional UNIX systems and embedded development on hardware constrained systems, getting rid of C is an impossible task.
- Tade0 9y ago> since everyone knows that C is a greybeard language and, therefore, not cool. As a person who works as a front-end developer but after hours writes almost exclusively in Rust I think I could shed some light on what's going on here: Since JS is so accessible a lot of the folks who work with it don't even have a formal education in Computer Science(like the author, who's a CS student), so many of them never touched a compiled language in their life, not to mention subjects regarding CS. To these people most of the concepts in C(like manual memory management) are entirely foreign. It's not that they don't _like_ C, it's that they're utterly unaware of the mindset one has to have to write things in it. EDIT: grammar.
- tcfunk 9y agoIn my purely anecdotal experience, learning web-based technology over C/C++ was not a choice I made personally. It was a career path that was foisted upon me by job availability and hiring requirements. I have yet to see a job posting for a fresh-off-the-boat C developer. It's nearly always 5-10 years industry-related experience required. Web, on the other hand, seems more willing to take on the new guys.
- agumonkey 9y agoeven MIT caved in, using python + libs in courses. They clearly said: today people are wiring solutions. I find it a bit problematic because when there's no solution you feel lost. But they have decades of experience .. I hope it's their very best insight.
- photonios 9y agoHonestly, I think you underestimate things a bit. In a "modern" development stack you rely on a lot of work by others. But it's far from the "glorified plumbing" you describe. It's not as black and white as you describe it to be.
- soundwave106 9y agoTo me, your basic "high level programming" job (which usually includes the JS folks with their modern stacks) typically is all about translating business / application requirements into logic that computers can understand and interfaces that people can use. Certainly, as a higher level programmer, I do think it is great to know as much lower level concepts as possible (it helps your higher level programming skills). But the truth is, business simply wants to Get Shit Done Fast. And having frameworks or libraries do a lot of the work for you saves a lot of time. Hence the huge amount of usage of "glorified plumbing" in the field. (I don't think even C++ folks are immune to the "glorified plumbing" effect, eg: they have Boost, Poco, QT, etc.) As far as I know, the separation between this side of programming and the more mathematical / inner detail "engineering" oriented side has always existed. (When I went to college, the "higher programming" pathway also had business courses, where the "engineering" side concentrated more on algorithms and the like. Now, even the business programmer folks did take one course in C++ back then...)
- jsudhams 9y agoWe do have programmer, developer and engineer. I assume the framework developer will come in league of developer while the user is programmer http://chrislema.com/programmer-developer-engineer/ http://chrislema.com/programmer-developer-engineer/
- archagon 9y agoOK? Sounds like "learning" at work to me. Besides, things are better grokked when explained from a variety of angles, be they top down or bottom up.
- agumonkey 9y agoAll this screams to me "education". The self taught diy thing is great, but on mass scale it's inefficient. If all these devs (I could include myself) could spend 6 months doing all this together sharing the common patterns and then go out fixing other problems ? Also SICP/HtDP
- chickenfries 9y agoOne, who just has a free 6 months? Two, do you honestly think you can fit a comprehensive CS education that would satisfy people like you in six months?
- agumonkey 9y agoGood points but what these people learn in segments in random order would probably fit into 6 months. I don't even believe CS education fits in 5 years anyway. I was just trying to suggest how to avoid diy lib chaos.
- throwawayjava 9y ago1. Most westerners born outside the USA. And in the USA anyone willing to take out a loan. 2. The core requirements for a cs major at a typical university (read: not CMU,MIT,Stanford,Berkeley) and especially at a non flagship is basically 4 or 5 courses, which you can for sure cram into 6 months if that's all you're studying. Personally, I'd rather work with people who learn some part of that on their own (or even not at all) but have a stellar education in reading, writing, and math. The former are often provided by good high schools. The latter not so much. At least in the states. But if all you want is just the core fragment of just the cs, six intense months are enough.
- pjmlp 9y agoHaving a 5 year degree in Informatics Engineering, I doubt very much you could cram that much in 6 months. Not at my university, with the amount of stuff we had to do, unless in the 20+ years that have gone by, they got the quality level down.
- jnbiche 9y ago> The more I read, the more I felt that the author was long-windedly discovering FSM's Then you missed the main point of the post, which was event flow, not state management. I'm wondering if sometimes older devs (I'm one) read these posts in anticipation, just waiting to find something that they recognize from elsewhere, just so they can say "aha, that's just X, nothing more!". In this case, you did recognize that yes, you can use a FSM to store application state, but the point of the article was much more event flow, specifically unidirectional UI architecture. It's not a new thing, by any means, but I thought it was a well-written post on how she/he expanded their understanding of this pattern. > giving it all a new fancy name, and blogging about it Are you suggesting that in this case, unidirectional UI flow is just another name for a FSM?
- LolWolf 9y agoI guess technically everything physical is an FSM with enough states, but that wouldn't be a particularly strong statement. That being said, I'd argue a lot of such posts are of that form (one big idea that's well-known in TCS) modulo some amount of additional cool/novel/well-exposed/interesting stuff I didn't know before (the latter of which is what I really read the post for).
- mmjaa 9y ago>Are you suggesting that in this case, unidirectional UI flow is just another name for a FSM? Yup. The UI reads its current-state data, which comes in on an event queue, and renders the display accordingly. This is a state machine.
- jnbiche 9y agoWell, as someone else said, just about anything physical could be modeled as a state machine. That doesn't mean we use the term state machine to describe just about everything physical. Are you seriously suggesting we abandon terms like "unidirectional UI flow" and just describe those architectures as state machines? You would be missing the most important part of the term, which is the flow of events. State machine says nothing about that. I mean, if you're reducing the event flow of a UI to a state machine, why use the term MVC, right? It's just a state machine at heart, right? A lexer? Oh, that's just a state machine, forget about the term lexer. The various Markov models? Oh, just a state machine. etc. etc.
- landave 9y agoI couldn't agree more, and I've always been a strong advocate of learning things bottom up, as opposed to top down. However, it always amazes me how powerful abstractions such as high-level languages are. In particular, it allows people who know virtually nothing about the underlying mechanisms to develop cool applications. This is a great thing, and I think we should value it, even though it comes with some major problems.
- alacombe 9y agoThere is plenty to re-use in C, eg. BSD's queue.h or linux' list.h for linked list alone. Because the author choose not to do so doesn't mean it is the fate of the whole language. Though, it is indeed a little harder than firing "npm".
- Nursie 9y agoIs it? On (Debian) linux boxes apt-get install <package>-dev and away you go, there's literally the whole platform ecosystem there for you to use.
- deleted 9y ago[deleted]
- deleted 9y ago[deleted]
- noxToken 9y ago> I'm not trying to be overly critical, but for a lot of us, "discovering that C-based apps are, weirdly, similar to what us React-ites are doing" sure seems like a step backwards from real stack competency. This is something that I try to impart on all new hires. Collective we have been making great strides in this industry lately, and in my experience, the more inexperience devs tend to get blinded by all of the shiny. This isn't inherently bad; a lot of CS breakthroughs are tough to learn without the appropriate domain knowledge. But practical stuff that most devs use ins't anything fancy. It's the same concepts from years ago with config files attached to it. We don't stress learning algorithms so that you can write a perfect quicksort implementation from memory. We want you to know the fundamentals so that tomorrows new technology becomes trivial to learn.
- sametmax 9y agoThe reverse is true. I meet quite a lot of low to middle level programmers that stick to what they know because it's "the basics", and hence completely lack in experience in: 1 - Writing elegant modern code Working with experienced C / Java coders to write proper Python is a challenge. They tend to use twice to many lines, ending up with slower and less readable code. They don't use the additional productivity to produce cheap goodies like generated doc, more unit tests, etc. They over-engineer stuff, but let the user experience down. And don't ask them to setup a server without the help of a sysadmin. 2 - Trading efficiently machine time for coder time Aka you cost 100 $/h, a bigger server cost the same amount a month. Keep the double nested loop and go code something else. And please setup code auto reload and preprocessors. Because THAT will save time and money down the road. 3 - Knowing the modern ecosystem and how the stacks fit together No you don't need share this across threads and set a mutex here, put that in redis. Don't write that in XML, you have JSON/YAML/TOML for that. Actually don't write that in a file, you have sqlite. No, you don't want to JOIN that, you have Arrays and JSON types in PostGres. If you got a lot of those, mongo or elastic search will do. No you don't write sockets manually, you have http, zeromq, wamp and the likes to do 99% of the jobs. JSON is too slow ? You have bson, msgpack, protocol buffers... Yeah, this ORM is slow. But it generates the entire validation system, including HTML forms. And it allows for 12 plugins to share a common API to provide auth, history, permissions, registrations, a REST API, security measures, sanitizing and data validation for free. Plus the server has 32 cores so just go with it. 4 - being able to keep up with user expectations No I have no idea how to code in assemble. I can tell you however that the search completion you don't want to add here because it's too much work would prevent the user to think your app is from 2004. And I can get decently performance version of it for tomorrow at a cost effective price. ---- Bottom line, everybody has limited time and resources and can only learn so many things at once. Also different industries have different needs. And sometime you want low level programmers, sometime you want high level programmers. One could hire somebody who has the skills of both, but you probably can't afford him or her. And he/she is probably not interested this mission anyway
- nv-vn 9y agoThere's a lot I could address with your comment, but since I'm short on time here, where are you getting servers that they all cost the same amount regardless of specs?
- fnl 9y agoI don't think the article was that bad for "junior-JS-to-JS-dev talk", which I think is clearly the main audience. Yes, I'd agree, for any seasoned dev, an article about the basics of functional programming, state machines, and the basics of unit testing and API design is a tad boring ;-). But that's no reason to get that upset about an article that clearly wasn't written for such an audience. Rather, such a response is not exactly encouraging those "kids" to learn complex programming concepts/languages in the first place, I think, and instead seems a bit offensive, to be honest.
- jnbiche 9y ago> such a response is not exactly encouraging those "kids" to learn complex programming concepts/languages in the first place, I think, and instead seems a bit offensive, to be honest. Yes, exactly. I mean, this dev is someone who clearly is working toward a deeper level of understanding of CS concepts, and here some people seem to be criticizing him for that. It's frustrating.
- MrBingley 9y agoAh, but you forget, then we can't browbeat the JavaScript-kiddies with our own seasoned superiority. (adjusts monocle)
- fnl 9y agoHmm; I guess that means a solution would be to personalize HN rankings on the similarity of voters' earlier votes on other articles with your own voting behavior (as a proxy for article preference...) :-)
- zbtaylor1 9y ago> It's frustrating. It really is. This "community" can be very unwelcoming. I'll never understand what motivates people to shit all over content they consider below them. Is it really that hard to pass by without shouting "I'm smarter than you!" at everyone?
- donkeyd 9y agoI consider myself a self-taught professional developer, since it's become the job that pays my bills, but I've never had any formal education on the subject. I regularly find out things like this, because I haven't been educated on the subject and because I don't have infinite spare time to study programming patterns. I know they exist and when I feel the need to, I look them up, but otherwise, yeah; "npm -i <all the things>" all the time. I don't feel bad about this at all, since my colleagues describe me as a competent developer and my employer can't find enough people for all the work we have to do. If we only wanted to hire developers who understand C, we'd have a really big issue.
- yaseer 9y agoIs this the state of things today...from the top-down, trickle through the stack learning 'the things' Yes, the path most people will take today is from high-level languages and high-level abstractions, down to low level abstractions. It's not any better or worse than a bottom-up approach for learning. The fact that people are going down through the stack, trying to learn and understand things as they go is to be celebrated, not to be rued. A top-down approach for learning makes logical and logistical sense in 2017, given the demand for developers operating on high-level abstractions. The bottom-up approach made sense, circa 1972 when C appeared. Neither approach is 'better', IMO.
- taneq 9y agoMy grandad used to say if you learn to sail a small boat properly, you can then learn to sail a big boat, but if you learn to sail a big boat first, you'll never really learn to sail a small boat properly. I think the analogy holds here.
- eecc 9y agoWell, what counts as big and small in this case? C or Js?
- 1_player 9y agoI suppose small == low level (C), big == high level (JS)
- Sacho 9y agoWhy can't you learn to sail a small boat properly after learning to sail a big boat? I don't see how the example works in the first place.
- smallhands 9y agowhat the grandfather is trying to say by my own understand is learning to sail small boat when big boat sinks small boat sailing skill is the only thing that will save your hide.the old man is wise
- njharman 9y ago> Is this the state of things today I don't think that is just today (except the blogging aspect). That is how it always has been. Developers learn from experience, learn from doing.
- dvfjsdhgfv 9y agoIt's a general trend. Many young developers rediscover old things and describe them using familiar terms. At first it amazed me, then I understood it's more or less natural and there's nothing we can do. It's like when your son discovers the Beatles and gets excited.
- Raphmedia 9y agoWhat can I say? Learning the language du-jour landed me a high paying job right out of school. I had a choice at one point : Join the workforce doing web work (and make money right now) vs. spend more time in school and learn more while gaining debts and making no money. Right now I am debt free, living a good life writing modern JS. In my free time, I try to learn more low-level CS knowledge. It's however hard to justify the time spent doing this since none of it is of use during my day job. If University was free and we didn't have to work to eat, I would know everything from the ground up. Sadly, this is not the world we live in.
- jmaygarden 9y agoStoring every character in a doubly linked list seems like an extremely inefficient use of memory. Depending on your architecture, that could use 24 bytes per ASCII character (if the char in the struct is padded with 64-bit pointers). I imagine that vi wouldn't have gotten very far if it had been that memory constrained.
- ClassyJacket 9y agoRight. Wouldn't it be smaller to even use UTF-32 and just jump forward and back in 4-byte blocks?
- moefh 9y agoYes, a common way to store the text in editors is a gap buffer[1]. It allows efficient text insertion/deletion in one point and doesn't have too much overhead. [1] https://en.wikipedia.org/wiki/Gap_buffer https://en.wikipedia.org/wiki/Gap_buffer
- coldtea 9y ago2MB of characters in Atom use 300MB of memory or more, so it's like 150/1 -- compared to 32/8 that's nothing.
- jmaygarden 9y agoOK, but Atom isn't pitched as a "lightweight vi." If I want to ssh into an embedded device and view a 2MB log file, then I sure wouldn't want that to require 300MB of RAM.
- red75prime 9y agoActually, it's 64*3/8 = 24/1
- clarry 9y ago> Depending on your architecture, that could use 24 bytes per ASCII character (if the char in the struct is padded with 64-bit pointers). Quite possibly much more than that because of allocator overhead. Main sources of overhead are rounding (i.e. the allocator might give you a 32-byte slot when you ask for 24 bytes) and bookkeeping (it needs to keep track of all allocations, which tends to require the storage of addresses and bitmaps .. in some kind of a data structure).
- jnbiche 9y agoNice article, good summary of the purpose of unidirectional UI approach like Redux's, although it doesn't get as much into persistent data structures as maybe it could have. What's the point of the exclamation mark after certain function names? Is that a pseudocode thing? Is that supposed to be shorthand for an impure function? (if so, not sure why `handleKeyboardEvent` doesn't have an exclamation mark.
- scarface74 9y agoSo this guy has rediscovered how we did GUI development back in 80s and early 90s?
- robotresearcher 9y agoYes. He's a student. It's cool.
- gruebite 9y agoIt is still occasionally the way we do GUI development. What's your point?
- deleted 9y ago[deleted]
- agumonkey 9y agonot C, but probably very C useful http://scienceblogs.com/goodmath/2009/01/26/ropes-twining-together-strings/ http://scienceblogs.com/goodmath/2009/01/26/ropes-twining-to...
- mstade 9y agoI learned something new, thank you very much!
- josephg 9y agoI made one of those in C, using skip lists instead of trees so it wouldn't need rebalancing: https://github.com/josephg/librope https://github.com/josephg/librope It could happily do 5M random single character edits / second on my old laptop. Its wild what you can pull off with C. Much more memory efficient too (it uses about 4 pointers of overhead per 180 characters). I'd love to see a version which supported traversal using more methods though - that library needs to support searching by line as well as character count. I tried porting it to Rust a few times but unfortunately couldn't figure out how to port it without introducing indirection everywhere. Modern 'C replacement' languages don't let you do the same funky memory management tricks. (Like using a dynamically sized array at the end of a struct allocated in the same block.)
- smaddox 9y agoImplementing efficient datastructures in Rust often requires `unsafe` code. Unlike in C, though, you can use Traits (which provide both static and dynamic dispatch, depending on usage) to provide a safe, zero-cost interface.
- Ar-Curunir 9y agoJust to nitpick, Traits aren't (just) what make Rust fast. There's a lot of help from the compiler and the type system that allows the final compiled code to remove bounds checks in a safe manner.
- josephg 9y ago
- agentultra 9y ago> In other words, UI programming is about mapping incoming events to a series of effects. Sort of like programming with Monads. This is one of the reasons why programming with Monads is so powerful: the programmer can explicitly compose and control effects. Good on the author for digging in and learning new things. I'd recommend following up with reading the source to vi and doing some research on programming patterns of the day. One of the things we're pretty bad at preserving is context; it'd be neat to read about what the author discovers (ie: why was vi written the way it was? What did the original authors discover? etc).
- mstade 9y agoI've tried to push pretty hard for writing rationales for any project we make, and we've also tried to adopt making records of "big decisions" including a tl;dr of the context. Unfortunately, these tend to take a backseat to "moving tickets from left to right on a board" and in prioritizing what gets on the board, unfortunately writing things down for posterity simply never makes the cut. :o(
- agentultra 9y agoThose who cannot remember the past are doomed to repeat it. And as I like to say: software is built in the image of the organization and processes that created it. If the organization I work for doesn't openly condone it I still journal what I work on and spend time on documentation and specifications before we work on an important feature or project. If we make a mistake or forget why a certain architectural decision was made I've found it immensely helpful to have context for those decisions. It helps make planning changes much easier.
- jnbiche 9y ago> This is one of the reasons why programming with Monads is so powerful: the programmer can explicitly compose and control effects. Yes, it's true, but lest anyone come away confused by this statement, monads are about much more than effects. I understand that's not what you're saying here, but my first months of dabbling in Haskell were marked by a deep misunderstanding that monads were used for side effects, and nothing more.
- alacombe 9y agoIt is not surprising that C gets that much of a bad reputation when devoloper show such poor capacity at managing errors; malloc(3) return values are never checked and everything is expected to always succeed, throughout the source tree.
- rvense 9y agoOn a modern Linux kernel in its default configuration this is AFAIK actually the case? The kernel overcommits memory. http://www.win.tue.nl/~aeb/linux/lk/lk-9.html#ss9.6 http://www.win.tue.nl/~aeb/linux/lk/lk-9.html#ss9.6
- bradfa 9y agoDo other *nix systems behave differently regarding overcommit of memory and malloc() really only erroring out when virtual memory is exhausted (which basically never happens)?
- megous 9y agoIt can happen, I had various issues with my VPS provider which set limits on virtual memory use in his virtualization solution. Programs would crash with malloc failures despite overcommit being enabled.
- megous 9y agoIt can still fail. Also it is not very bright to depend on some kernel configuration in order not to crash unpredictably. Also it's not portable. Some targets don't have MMU.
- pjmlp 9y agoThere are languages that don't allow the programmers to do such kind of failures.
- alacombe 9y agodon't focus on malloc(3), it's a problem of thinking the design of the code and the relevant backpressure if the state goes SNAFU.
- innocenat 9y ago> In other words, UI programming is about mapping incoming events to a series of effects. So I guess the word `event-driving programming` is lost in time. And I don't think the Unidirectional pattern described is suits for C programming. When I see people use C, I think performance, and unless the compiler optimized it away the state mutating function is gonna cost a lot of unnecessary memory copy. And worst offender is that unless you have React-like UI diff-ing library, it's gonna be a costly entire screen redraw event for the most simple update.
- clarry 9y agoWrite a game or an editor with support for macros and see if it isn't faster to first mutate the state and then finally render, rather than doing thousands of ad-hoc screen updates, most of which won't be visible in the end anyway.
- innocenat 9y agoAnd then we arrive at dirty marking, etc. Unless you also consider that state manipulation (which I don't think it is).
- DSMan195276 9y ago> unless you have React-like UI diff-ing library, it's gonna be a costly entire screen redraw event for the most simple update. He's using ncurses, which actually does that - it only redraws the parts of the screen that change. It can require a bit of coxing at times to ensure that things get redrawn properly but I'm pretty sure he's good - I didn't see anything in his code that would force a full redraw every update.
- radarsat1 9y ago> He's using ncurses, which actually does that - it only redraws the parts of the screen that change. Heh, when I first read about React, my immediate reaction was like, "oh so it's like ncurses for the web, cool, makes sense."
- crummy 9y agoI'm new to frontend development. Is this kind of how Vue works?
- skywal_l 9y agoWhat is the difference between Event Sourcing and the Command Pattern here? For decades the Undo/Redo functionality has been implemented by the Command Pattern it seems. And looking at what Event Sourcing is, it looks a lot like the Command Pattern which purpose is to encapsulate into an object a side-effect performed on some data structure. That object can then be executed at a later time, reverted, logged, etc...
- zellyn 9y agoI'd like to post a purely positive, encouraging comment here :-) Thanks for the article, and good job implementing an entire editor from scratch in C! That's impressive. Also, as a very accomplished programmer who happens not to have done much recent UI programming, who has read quite a bit about React/Redux/Rewhatever, Elm, The Haskell School of Expression, etc., I find articles like this extremely helpful: you took a simple example, and clearly and straightforwardly demonstrated the underlying goals and principles of "Unidirectional UI". While I mostly "get it" already from reading articles on React-based architectures, clear reiterations of the idea are a huge aid in getting the concepts solid.
- fnl 9y agoThank you, for this! I could not say it better/nicer. I was getting upset with the overwhelming negativity here. Monday morning syndrome?
- mcjiggerlog 9y agoUnfortunately HN can be unnecessarily negative sometimes. Thanks for the interesting article!
- fnl 9y agoSorry, don't get me wrong - I'm not the author; I just wanted to know why HN had voted this article to #1, and then was even more confused by the tone in the comments. Hopefully, the productive comments will end up on top, eventually!
- olddevanon 9y agoIt's because the challenge he set himself isn't hard and he didn't do a particularly good job of it either (other comments have covered that so I wont reiterate it) yet he is soapboxing his experiences as if the topic isn't entry-level stuff. And I mean "entry-level" quite literally as you learn about event-driven programming in high school or equivalent IT classes. This isn't something you need a CS degree to learn. I mean kudos to the guy for trying something new but honestly I'd expect anyone working as a developer in IT to have learned this much before calling themselves a professional. And that includes Javascript devs since so much of frontend development is event-driven anyway. Personally I get a little fed up by just how _bad_ many frontend developers seem to be these days. I'm not tarring everyone with the same brush as I'm known some really amazing frontend devs too (though they ususally consider themselves full stack). But I've lost count of the number of Javascript developers who I've had to explain HTTP status codes and the difference between GET and POST. It feels like frontend development is a place where people go if they like the idea of coding but can't be bothered to learn how to actually programme nor any of the principles they're building their code on top of. Thankfully the topic author bucks that trend a little but even in his case the lessons he is learning are painfully basic. By the way it's a bank holiday (long weekend) in the UK so no Mondays blues from me. :D
- pier25 9y agoOnce you move to making mobile or desktop front end you appreciate how easy front end web dev really is. Contrary to popular opinion I think the DOM, HTML, and CSS, are an awesome way of defining and styling a scene graph. When I did some C++ front end I missed them every day.
- pjmlp 9y agoI bet you didn't use any of VCL, Windows Forms, QML or XAML on your C++ front end.
- nodivbyzero 9y agoHow about MFC or WTF or WinAPI?
- pjmlp 9y agoThey are good if one likes to write boilerplate with lots of C style coding in a C++ application. MFC always suffered from not being as high level as OWL or VCL, because the internal devs at Microsoft thought that Afx (the original implementation) was too high level. By WTF, I think you actually mean WTL, which is based on ATL, full of templates and low level COM style programming. Another one that gives no pleasure using. WinAPI was already out of fashion on the Win16 bit days, I was already using Turbo/Borland C++ with OWL on those days. The only reason to use Win16 directly was to wrap APIs not exposed to OWL. Sadly due to how Borland got themselves mismanaged, OWL lost to MFC in the early 32 bit days, and only enterprise customers with deep pockets adopted C++ Builder with VCL, which allows for VB/Delphi style programming with C++.
- deleted 9y ago[deleted]
- dmlhllnd 9y agoFor anyone interested in building a text editor, I really enjoyed working over this tutorial: http://viewsourcecode.org/snaptoken/kilo/ http://viewsourcecode.org/snaptoken/kilo/ The author builds a terminal-based text editor in C from scratch. It's very well written and the incremental diff-style format makes it easy to follow along.
- mi100hael 9y agoDat JavaScript coding style
- dreta 9y agoIt's worrying how sometimes the most basic programming concepts can appear revolutionary to web developers. So much so, they've recently stumbled across the concept of a read input-update-render loop, and are now trying, with frameworks like React, to contort the DOM tree, just to get back to how UI was programmed since decades. There's a fairly old concept called "immediate mode UI", which even gets rid of the tree structure, and keeps the whole state on the user side, giving you full control over when elements are updated and where they are placed. These days it's used mostly in video games, since they already rely on a 60 FPS loop, and the UI complexity tends to be low. If not for the necessity to use standard platform form elements due to their various quirks and interactions with the system, I'd be doing UI programming only in immediate mode with custom controls, simply because how convenient, and simple it is.
- whowouldathunk 9y agoBattery life would take a dive if everyone adopted immediate mode UI for apps. The compromise is something like Win32, where the OS tells you which rectangles in your app to repaint so most of the time you're not doing anything. Both of which are a ton of code if all you want to do is display a list of TODO's with custom styling vs. <li> in markup.
- dreta 9y agoThe rate at which you have to update, and what you have to update doesn't change between retained and immediate mode. The only difference is that, with retained mode, the library you're using has, by design, all the knowledge it needs, so it can manage all of that for you. The whole point of using immediate mode is to get rid of this black box from your program, so that you can explicitly state what you want to happen, when, and in what order. It's only "a ton of code" if you write everything from scratch, so i fail to see how that's an argument.
- whowouldathunk 9y agoI'm using "immediate mode" to mean: while (true) { processInput() updateState() paint() } That will kill battery unless you write code to not update until input or app state changes, in which case you're building up to your own retained-mode system.
- arximboldi 9y agoVery interesting work! It seems that educational text editors are becoming a trend after Antirez published his :-) Excuse me the shameless plug, I'd like to show mine too: https://github.com/arximboldi/ewig https://github.com/arximboldi/ewig It is written in C++, but using a style that is unlike what most C++ developers use: it is composed mostly of pure functions. The architecture is very much like that of Elm programs, and there is even a `store` class like in Redux. Like the project from OP, it is about 2K lines of code. But it also supports asynchronous loading/saving, copy-paste (you can copy-paste a 1GB file instantly), very robust undo, dirty markers, UTF-8 (not perfect), etc. The magic? Immutable vectors based on RRB-Trees. This is like the vectors in Clojure/Scala, but also supports log(n) slicing, concatenations, insertions---these operations are fundamental for a text editor, and I'd say, to most interactive software supporting big data models [1]. The code has been written in a style as simple as I could. I'd like to think that even non-C++ developers might be able to understand it. It might be specially interesting for web developers invested in Clojure, Elm or Redux and the single-atom architecture. Probably one day I should go ahead and just write a blog post about it or a tutorial or something. But so far I don't have a blog I am not really a social media person. The code is still moving also... PS. And thanks a lot to @kostspielig her help writing and reviewieng the code! <3 [1] The data-structure can be found here: https://github.com/arximboldi/immer https://github.com/arximboldi/immer
- jnbiche 9y agoAwesome project, you're inspiring me to pick back up a text editor project I had started to learn Rust a while back. Yours is much more featureful, however! By the way, if anyone else is thinking about doing the same, HN had a great discussion on an article (also very useful) on the various data structures one can use for text editors: https://news.ycombinator.com/item?id=11244103 https://news.ycombinator.com/item?id=11244103
- arximboldi 9y agoThanks for the link and the encouragement! You have your Rust project somewhere online? I'd love to take a look at it. I sometimes fantasize about rewriting Ewig in Rust, as a learning project (have been reading about it but didn't dare to write code in it yet). But I'd like to use RRB-Vector there too. Sadly, this data-structure is not really trivial to implement... (the concat algorithm in particular). Maybe one day I'll find the time :-)
- YSFEJ4SWJUVU6 9y agoA cursory look into the linked github pull request changes made me spot this, and I must admit that never in a million years would I've thought to erase the possible endline character of a string returned by getline with this: line[strcspn(line, "\n")] = 0; I don't think I'm going to start, either, even if it is a nifty oneliner. Anyway, I've always found this kind of little projects a good sport.
- eplanit 9y agoWise choice.
- YSFEJ4SWJUVU6 9y agoThat's not correct. If the scanned string doesn't contain any of the search string's characters, strcspn will behave like strlen, and the snippet ends up doing effectively nothing. However, the statement is inefficient in what it does (and even then, not the most obvious way to achieve that, which your comment also highlights in a roundabout way).
- deleted 9y ago[deleted]
- alkonaut 9y agoIs the (pseudo?) code there for state mutation representative of a widely used pattern? It looks like using a pattern from a functional programming book, but applied to mutable data. What I mean is this snippet: function handleAddTodo(state) { if (!newTodoField) { state.error = 'Empty field!' } state.todos.push(state.newTodoField) state.newTodoField = nil return state; } This looks like a function newState = fun(oldState) but there is one huge problem: the new state is the same data as the old state? In a Rust-like type system this might be OK because you couldn't accidentally keep using the original state after sending it to this method, and in an immutable scenario there would be no problem because you created a new state instead of mutating. But this looks exactly like mutating the argument sent to a function. So out of curiosity, do any modern UI frameworks in JS (this looks like that type of code) do this, or was it just an unfortunate example?
- 1_player 9y agoVuex works like this: you actually mutate the state instead of creating a new one as it's expected with Redux. But this mutation takes place is a single, controlled place (in the store mutation functions), so you get the benefit of centralising the state management code and avoid the cumbersome immutable transformations patterns which Redux requires. That said, after having worked with Vuex, I much prefer the immutable newState = f(oldState) pattern used with Redux.
- nevon 9y agoThat's an unfortunate example. What you described as `newState = func(oldState)` is (conceptually) how practically all of this generation's state management libraries are modelled.
- l_pan_ 9y agoThis is not an unfortunate example. With the absence of persistent data structures it is inefficient or difficult to write the state transition functions as pure functions.
- disquist 9y agoI am a novice in this area, so forgive me if I am missing something, but I have some questions regarding the two approaches in the article, specifically if there is a performance trade-off being made between them. To my untrained eye, the initial version seems to be doing a minimal set of updates based on the input it receives, whereas the latter version will call the monolithic render procedure no matter how small a change is made to the state. Does each of the sub-procedures in renderTodo! check internally if the state actually changed (by keeping a copy of the previous state?), or do they just unconditionally re-render the entire UI? If the latter is true, then doesn't this supposedly better way of structuring code come with a large performance penalty? Or is it simply the case that this penalty is outweighed by the added test-ability and improved consistency of the state? I believe that React and similar frameworks run a diffing procedure to find out which parts of the UI actually need to be updated (so a more minimal set of updates is actually applied). In the first version, however, it seems like the same diff occurred naturally as part of the code's structure - only a subset of the render* functions are called - and therefore the diff does not need to be computed at run-time. Is this something worth being concerned about, or is letting the framework compute the diff on every state change not that big of a deal?
- mercurial 9y ago> I believe that React and similar frameworks run a diffing procedure to find out which parts of the UI actually need to be updated (so a more minimal set of updates is actually applied) That's true. React diffs the virtual DOM and applies the changes to the actual DOM. However, the fastest is still to diff the actual data to be rendered, and determine whether the render function needs to run at all (this is opt-in via React's shouldComponentUpdate() lifecycle method).
- jboons 9y agoIf you plan on allowing future employers to look at your Github profile, you might want to change the way you write your commit messages. > REFACTOR: :hocho: future queue (I was retarded) Not exactly an appealing commit message.
- deleted 9y ago[deleted]
- WalterBright 9y agoAnother C tty oriented text editor is the classic MicroEmacs: https://github.com/DigitalMars/me https://github.com/DigitalMars/me I learned a lot about programming from reading the source code to it. It's a gem of clarity and design (and you could reasonably argue that many of my changes to it messed it up).
- zoom6628 9y agoAll i can say is "watch this kid!". He is showing the motivation, perspectives, insight and intelligence to be able to do important work in the future. Great article and the C code worth reading to learn from. Thanks for sharing and looking forward to reading future blogs and seeing what you create.