18 ms·
Simple-twitter: A bare-bones Twitter clone implemented in a single file
- blakesterz 7y agoIt might be better to change the link to the main README: https://github.com/Gabriel439/simple-twitter https://github.com/Gabriel439/simple-twitter
- apetresc 7y agoA note to those who might dismiss this without looking at it carefully because you assume it's just some SPA that mocks the Twitter UI: it's actually a NixOps file (with everything inlined) that deploys the entire stack, including a full backend and database.
- cblum 7y agoThis is the first time I’m seeing that. It’s so beautiful. It’s elegant. I can understand it. Why can’t the world move in that direction, instead of the insane Kubernetes hype that’s prevalent these days?
- bitlax 7y agoLibraries, helper functions, support, etc.
- agumonkey 7y agoPlausible. There's nix and guix, and maybe others. There's intetest and worth but it may take time.
- ar_lan 7y agoCurious - what don't you like about Kubernetes?
- movedx 7y agoRepeating my reply to this question asked by someone else above. I genuinely want to engage people on this question. --- My problem with Kubernetes is people adopt it without understanding it. They adopt it because everyone else is without ever asking, "Why?" I've installed and managed a simple K8s cluster before now and it was a nightmare (this was only a year ago.) It wasn't until we moved the management of the cluster to a managed service that it became worth it. It was at THAT point it was worth containerising the application(s) (another complexity to overcome) and letting K8s handle the deployment and scaling. I'm worried that as an engineering culture we're not pushing back enough and saying, "Yeah K8s is cool but look: do you really need it? It's very likely you don't". For me to automatically recommend K8s to my clients I'd need to see a (near) zero friction deployment options that's fully feature compliant and truely fully managed. It's at that point I would be happy to say, "Sure! Let's go with K8s and just write YAML files to deploy our containers!" (And then there's the whole debate as to whether or not you even need a container around your monolith... probably not. Then the next debate about people starting out with microservices when we all know that's not a good idea.)
- ar_lan 7y agoI work with Kubernetes quite a bit, so I'm reasonably knowledgable on the pro's and con's. I definitely think there is a misunderstanding about what Kubernetes solves. I think Kubernetes is very good at helping structure very large applications where a split of micro-services makes sense. Most start-ups don't need it - it's likely overkill, and unless you go with a vendor you're likely to set it up incorrectly. But it is an advantage in much larger, spread out teams if the culture surrounding all the teams makes sense. If sub-teams can handle their applications really well, which many companies have achieved, then it does provide significant benefits over monoliths. I think the problem you're noticing is that everyone wants to jump onto Kubernetes without realizing why it's even there - the same with micro-services. I shudder when I hear that from my friends with no more than 10 people on their development team, but I think it makes a lot more sense when I see teams of >200 complaining that their huge monolith is what causes the most friction.
- 7y ago
- YawningAngel 7y agoWhat do you think is wrong with kubernetes, out of interest?
- lhuser123 7y agoI think is referring to abstractions in general. Levels and levels of abstractions. Not always a bad idea but sometimes it ends up complicating things too much and burning new comers brains.
- ikeyany 7y agoThe levels of abstraction seem to be a hazing ritual that seems to be a point of pride sometimes. I also imagine it's good job security for those who spent years on these tools.
- jacobush 7y agoAw man. When I started in this industry we made new employees build their work PC from parts.
- cblum 7y agoYep, exactly this. Whenever I try to grasp it, I feel like things are being abstracted beyond comprehension. It doesn’t feel right. That, and the fact that it seems like you need to adopt about 100 completely heterogeneous tools to successfully manage a Kubernetes cluster.
- mroche 7y agoI went from using Singularity to bundle scientific tools for HPC cluster useage at my university straight into admining OpenShift at my current employer and I have to say it was not a smooth transition. Felt like a complete idiot for a good amount of time. But after spending a few months with it I’ve really gotten to see the power and use for the k8s infrastructure and its value as a tool/platform. And honestly, I’m digging it. It’s really cool stuff and once you get developers writing production services and applications that would otherwise have been virtualized on dedicated systems on it, they love it to for their speed of delivery and development. But we’re also managing hundreds of projects with multiple applications/services with high availability, so OCP/Kube makes sense for us.
- ioror93jf 7y agoBecause Google, AWS, & MS need everyone to focus on their needs, guh. If any of them could drive the Nix project from within their own walls we would be going that route.
- whateveracct 7y agoNetwork effects and money mostly (hype as you say). NixOps is a great tool..when it works. When it doesn't, it's not inherent. It's just that it is clearly not heavily invested in by any entity with a bunch of money.
- parhamn 7y agoI mean thats not doing much... You can docker run anything in a line. A few lines of terraform or any other deployment tool can run a binary on EC2 (and roll forward, and have state management, and so on). The complexity comes when you want to do something more interesting.
- movedx 7y ago> The complexity comes when you want to do something more interesting. And for 500,000,000 people.
- gravypod 7y agoKube is one layer that you use to get to a completely platform independent version of this. Look at kubecfg for an example of this being applied. When Cuelang, the next step after jsonnet, is finished and integrated with kubecfg it will be basically this with: 1. Run anything anywhere (no platform lockin) 2. The ability to talk about your arch using a shared dialect 3. Tooling that integrated with the API server for everything storage and DB (things like Rook), networking and security (CNIs), observability (Service Mesh), and many more abstractions. Kube is the low level dialect. The tooling around it makes it work like you want.
- ryan_lane 7y agoRun anything anywhere, as long as you don't any feature of the platform, except for compute. You're still tied in to the platform, or you're likely not doing too much.
- gravypod 7y agoYou can build controllers and CRDs to completely integrate any platform features you need all while maintaining a workflow with kubecfg and using kube to manage state recovery, roll out, and networking.
- movedx 7y agoMy problem with Kubernetes is people adopt it without understanding it. They adopt it because everyone else is without ever asking, "Why?" I've installed and managed a simple K8s cluster before now and it was a nightmare (this was only a year ago.) It wasn't until we moved the management of the cluster to a managed service that it became worth it. It was at THAT point it was worth containerising the application(s) (another complexity to overcome) and letting K8s handle the deployment and scaling. I'm worried that as an engineering culture we're not pushing back enough and saying, "Yeah K8s is cool but look: do you really need it? It's very likely you don't". For me to automatically recommend K8s to my clients I'd need to see a (near) zero friction deployment options that's fully feature compliant and truely fully managed. It's at that point I would be happy to say, "Sure! Let's go with K8s and just write YAML files to deploy our containers!" (And then there's the whole debate as to whether or not you even need a container around your monolith... probably not. Then the next debate about people starting out with microservices when we all know that's not a good idea.)
- anonytrary 7y agoI don't think declarative architecture and kubernetes are mutually exclusive. Seems like you could write a declarative file (terraform, cloudformation, etc.) that deploys a dockerized app to a kubernetes cluster in AWS.
- arianvanp 7y agoThing is; nixos has been architected for being declarative from the start. Whilst Kubernetes is a stateful REST API. Sure you can emulate a declarative view on top of a mutable thing (Think React and virtualdom), but having a declarative core makes declarative deployments easier to manage and more elegant. E.g. in Kubernetes automatically deleting a resource is still hard; It's hard to figure out when something is not "used" anymore. In nix, you simply run `nix garbage-collect` and all the things that are not referenced by your declaration are automatically deleted.
- Thaxll 7y agoBecause this is a toy demo that doesn't do anything, in the real world you need much more that than just to do something simple. Also it looks "beautiful" to your eye, from a programming perspecting it looks really un-readable if you don't use FP. https://github.com/Gabriel439/simple-twitter/blob/master/Main.hs#L174 https://github.com/Gabriel439/simple-twitter/blob/master/Mai...
- adrusi 7y agofrom a programming perspecting it looks really un-readable if you don't use FP. I don't mean this as a slight, and I myself am slacking in the same regard, but it's depressing to me that this attitude is so prevalent among professionals. There might be some good engineering reasons that tools like Docker and Kubernetes have much more traction than Nix, but "it's unfamiliar if you don't use FP" is a terrible one. It doesn't require that much investment to become familiar, and there seems to be many fantastic advantages to functional approaches. Why does our industry tolerate this laziness?
- ajdlinux 7y agoI haven't touched FP languages in years, but my first year undergraduate intro programming course was taught in Haskell... FP principles aren't so difficult that the average programmer can't learn them to at least a basic level.
- rimliu 7y agoAnd pretty much any widely used language already provides functional features.
- chongli 7y agobut "it's unfamiliar if you don't use FP" is a terrible one I get the sense that there is a large contingent of programmers who feel disdain for mathematics and FP gets caught in the crossfire. It’s unfair toward both mathematics and functional programming. I would love it if North American culture could adopt a better attitude toward mathematics in general. I think far too many people decide they’re bad at mathematics at some point in high school and never look back. This attitude is far less prevalent in many Asian cultures, where the emphasis is put on hard work instead of talent.
- panic 7y agoFWIW, the link posted here is just to the Haskell part. This is the fully-inlined NixOps file: https://github.com/Gabriel439/simple-twitter/blob/master/simple-twitter.nix https://github.com/Gabriel439/simple-twitter/blob/master/sim... (which is no less impressive -- fewer than 500 lines in a single file to specify a full web app!)
- edraferi 7y agoOh wow that’s super cool. I’ve been tracking Nix and NixOS for a while, but hadn’t heard of NixOps. Gonna did into that.
- OrgNet 7y agolol... a file that contains a bunch of files? is that an archive? or a set of instructions to download a bunch of files? what is the world coming to?
- chownie 7y agoThink of it as a declarative program, you describe the state of the machine as you want it and the nix package manager handles all of the rest. It downloads, installs, configures, builds and runs from your declarative description. This is my understanding of how nix works anyway.
- MuffinFlavored 7y agoCould the same not be done in a single Terraform file?
- akersten 7y agoIt's a nice demo. But there seems to be a surprising lack of validation? Seems like anyone can delete any other user, or post as anyone else, etc. Then again, I can't read Haskell, so I don't know if there's something preventing that at a higher level than the endpoint logic.
- whateveracct 7y agoDoesn't look like there is. I think the idea is for this to be a nontrivial example of a full-stack Haskell+Nix(Ops) project. The Twitter part is meant to be more familiar that robust. It's fair to argue auth should be included in a nontrivial example though. I honestly don't think it would add that much clutter either. Although unlike the other components, I don't know if there's a simple off-the-shelf Haskell solution for auth.
- wyager 7y agoServant (the typed routing system being used here) has pretty awesome and robust authentication support. I bet it could be added without too many additional lines.
- xwdv 7y agoI hope this is only the beginning of a series of popular web apps and social networks all recreated as pithy single file documents. Next should be Facebook.
- james_s_tayler 7y agoYouTube would be good too.
- bitlax 7y agoMight be nice if this title was changed. This is a toy app which is guaranteed to blow up at scale, but if the point is to show off a particular stack then maybe it should say so.
- derision 7y agoI don't think anything expects a project title "Twitter in a single file" to actually scale to real life..
- travbrack 7y agoThe fact that it's in a single file implies this. I don't think anyone would think they are trying to claim they can replace all of Twitter's production code with this single file.
- rco8786 7y agoI don’t think that either. But someone HN made a very spirited argument a few years ago that he could build and run Twitter in no more than 4 servers.
- james_s_tayler 7y agoDo you have a link to that comment? I really want to read it. That sounds like a HN classic.
- hokumguru 7y ago
- dom96 7y agoThis is cool and reminds me of the Twitter clone[1] I included as a coding exercise in my book[2]. It's a very good way to learn as a basic Twitter clone is relatively simple to implement. 1 - https://github.com/dom96/nim-in-action-code/tree/master/Chapter7/Tweeter https://github.com/dom96/nim-in-action-code/tree/master/Chap... 2 - https://book.picheta.me https://book.picheta.me
- jedimastert 7y agoA basic twitter clone sounds like a reasonable Hello World for new web frameworks
- sansnomme 7y agoOnly if you include stuff like auth and migrations. https://github.com/gothinkster/realworld https://github.com/gothinkster/realworld It's pretty easy to tell which frameworks are mature and which are not simply by looking at how many wheels that need to be reinvented.
- jedimastert 7y agoI don't know that I agree, or at least that's not always the goal. I've found that the more "wheels" already in the framework, the more opinions the framework has, and sometimes I just need something dead simple. Laravel, for instance, has so many really nice wheels, but it's organization can feel restrictive at times. web.py, on the other hand, has basically no wheels but I can drop into a project really quick. Maturity is a spectrum, and sometimes you don't need a wagon when a bike will do.
- sansnomme 7y agoThere are tons of Flask/Sinatra level abstraction frameworks. They bring nothing new to the table. Stuff like auth and migrations are difficult problems, which is exactly why you need a framework. Any halfway decent web dev can cobble together yet another expressjs lookalike, but there are few that can reliably build Devise type authentication solutions. Ever wondered why most build-a-blog web framework demo tutorials tend to conveniently skip user registration/auth?
- joewrong 7y ago" ORDER BY tweet.time DESC " sign me up
- nkozyra 7y agoI'll never understand why the stream cannot just default to logic like this or [my follows]+[non-rt/replies]+[desc by time] Best I can come up with is it'd make promoted comment more apparent?
- MagnumPIG 7y agoThat's exactly the reason. Ads can much more easily be camouflaged as real content this way.
- WilTimSon 7y agoIf only they weren't inane. I think Twitter is probably the worst in terms of 'promoted content' because it always seems to serve up the same ad several days in a row and it's always something surprisingly off-topic. I'd be browsing my feed full of political news, movie trailers, and animal photos... and get an ad for ketchup. How on Earth could I confuse that for a real tweet or something my friends would retweet? A ketchup ad? Mental.
- hombre_fatal 7y agoThis doesn't make much sense to me. You don't need complicated algorithmic sorting and filtering to inject an ad space after every fifth tweet. Even the client can do that.
- megous 7y agoClient does that. If you consume twitter via their API, you'll notice there are no ads there.
- hirundo 7y agoYou see many more outlier tweets with thousands of likes when your feed is interspersed with "most liked by follows and follows of follows", as opposed to just "tweeted by follows". I think that improves the signal to noise ratio of the feed. But yeah, I wish a simple timeline was the default, and twitter stopped switching away from it.
- cryptozeus 7y agoCan someone explain more ? I am not familiar with haskell. So is this like a Twitter like functional demo ?
- beders 7y agoOk, CLJ/CLJS, your turn ;)
- gigatexal 7y agoLove the raw sql queries here.
- grizzles 7y agoThis is a really nice one: https://github.com/rafaelalmeidatk/twitter-fullstack-clone https://github.com/rafaelalmeidatk/twitter-fullstack-clone
- cocochanel 7y agoThis made me want to learn haskell. What a clean code. Pleasure to read.
- samcodes 7y agoYeah, another comment said this is “unreadable” if you don’t do FP... I have done a little lisp + Elixir, but 99% of my coding has been in C-descendant languages and this was definitely readable.
- dmitriid 7y agoIt's readable because we know what we're expecting. Had the logic been just a tad more complex (e.g validation of input, login flows etc.), it would quickly become unreadable and unmaintainable to anyone not familiar with FP, or specifically Haskell: - there are fifteen LANGUAGE directives (what do they all bring?) - there's an ungodly amount of ASCII-art: What do any of these do, and in which contexts: ! @ :> :<|> And so on: just three things that caught my eyes looking at the code on my phone
- wyager 7y ago> just a tad more complex (e.g validation of input, login flows etc.) Servant (the routing library being used here) has pretty great and clean authentication support. https://docs.servant.dev/en/stable/tutorial/Authentication.html https://docs.servant.dev/en/stable/tutorial/Authentication.h... As for validation of input, what do you mean? Haskell tends to excel there as well, with the availability of parser combinator libraries like Attoparsec. > LANGUAGE directives (what do they all bring?) In a real project you hide these in a config file for your project. They're usually well documented, and you can usually guess what they're doing from the name once you have some context. > What do any of these do, and in which contexts: ! @ :> :<|> All of those except @ are just functions or types. You can look up what they do in the same way you would look up what any other function does. @ is the only one that's a syntactic operator, and it has 2 meanings depending on context. It's either specifying what a type variable should be, or it's pattern matching and binding a name at the same time.
- mark_l_watson 7y agoI really like the code. Sometimes I have problems following other people’s Haskell code but I found this web app to be very readable. Good stuff.
- TheUndead96 7y agoThere are a lot of very strong opinions in this thread on whether this code would be "production ready". I don't think that is the point here. This is awesome because of its brevity, it is like writing a ray tracer in 100 lines of C. It demonstrates that a task which might be perceived to highly complicated can be reduced to a file, of which the size many of us would just define a single class in such a system.
- kyllo 7y agoLove the use of quasiquotation here: import Database.PostgreSQL.Simple.SqlQQ (sql) ... let index :: Handler Markup index = do tweets <- query_ [sql| SELECT "user".name, tweet.contents FROM "user" INNER JOIN user_tweet ON "user".name = user_tweet."user" INNER JOIN tweet ON user_tweet.tweet = tweet.id ORDER BY tweet.time DESC |]
- jpochtar 7y agoSmall, easy to write/maintain approaches are at an evolutionary disadvantage vs classically "enterprise" styles. Easier to work with -> fewer people needed -> fewer people hired -> fewer people learn -> fewer people know. Now there's fewer people in the market who know Simple, vs many people who've learned OverEngineered (TM). Leadership wants to pick a language/style they'll be able to hire for as-needed. OverEngineered has a much larger talent pool.
- mrmonkeyman 7y agoPeople are vastly overestimating the load a few million folk generate coupled with vastly underestimating the compute of modern machines, assuming they don't throw away 90% of their cycles by using RoR-like setups. A clean simple Go/Rust backend will handle many many thousands on simple machines. We're talking near rPI's.
- gulperxcx 7y agoAre there any screenshots of what this looks like when in use?
- Gabriel439 7y agoI just added one. Thanks for the suggestion!
- kgthegreat 7y agoSlightly related - If you want a pre-categorised tweets feed with ability to add new categories, I have written one - http://trysensible.com/ http://trysensible.com/ (Open source https://github.com/kgthegreat/sensible https://github.com/kgthegreat/sensible). It comes with some standard categories such as politics, sports etc. but you can add whatever categories you want such as - music, academia and start adding your own curated list of keywords to support this category. This is written in golang and is open source https://github.com/kgthegreat/sensible https://github.com/kgthegreat/sensible
- webscalist 7y agoneeds photo and video upload
- Gabriel439 7y agoI just added a screenshot to the README
- k__ 7y agoHaha, awesome. It would be awesome if Nix, NixOS and NixOps replaced the current mess that is Docker and K8s.
- cyborgx7 7y agoA lot of people complaining that this wouldn't be able to hold the load of the original thing like that. I'd argue that all platforms attempting to be all-encompassing is a big problem right now. Maybe a single instance of a platform should really just accept as much load as this could handle in this form. They could federate with eachother to replicate the massive connected structure.
- asdfasdfdavid 7y agoAwesome slides, thanks for explaining!
- deleted 7y ago[deleted]
- omnifischer 7y agoOT very useful https://nitter.net https://nitter.net
- zemnmez 7y agoI learned more about haskell reading this than I ever have from anything else