I cancelled my Replit subscription
journal.paoloamoroso.com
journal.paoloamoroso.com
Edit: If I figured out a production app that had legs, I would move it away to save on costs. It's more of a test space for me.
I went the other way. I suppose it depends on the nature of the project, but I can spin up a new environment in a couple of minutes. Maybe a couple more if I need to configure a Docker container.
> so my vendor can be profitable
But this is a ridiculous notion.
I generally find superior value from sources that are less singularly profit motivated such as worker-owned organizations or public goods providers
If you're trying to start an actual business, it's very very difficult to get people to pay for your solution when a large incumbent can just pay people to use their competitive (potentially sub-standard) product by burning through mountains of, (sometimes not even their own), money. Or once you start to gain some traction, deplatform you from social/search, or bury you in frivolous lawsuits. It can be done, it's just not very straightforward (unless you also already have your own mountains of cash, or are very well connected). But, business is business, so sink or swim?
Otherwise, it's much easier to ride someone else's huge marketing budget (Apple App Store, WordPress plugins, ChatGPT etc.), which doesn't change the competitive landscape and gives those incumbents even more power (merchants/developers/creators touched by the platform's Midas finger become dependent on the platform because it's their income, then their users buy further into the parent system, etc.).
I do, actually, because I want my local natural foods co-op to stay in business.
But your point still stands. The alternatives aren't actually comparable, because they're for-profit entities, and I don't want my food budget going to them.
I do regularly; I don’t know if it’s the most expensive, but it’s absolutely not the cheapest. However, it’s a small market just a few blocks walk away and a small business and I value the proximity of it to my home so would like to see it continue to exist.
I think the decision should be reframed as: am I trying to spend as little as possible, or maximize value, which aren’t always the same thing.
(a) i do (ie intentionally buy from the most expensive store) (b) i don’t know if it’s the most expensive but it’s absolutely not the cheapest. (i.e. maybe i don’t, in fact)
> a small market just a few blocks walk away and a small business and I value the proximity of it to my home
This indicates that the alternatives are not completely equivalent.
cost = travel + item
In which case a corner store is, in total, more cost effective.
That said I do pay more for organic locally grown produce. Personal choice because those local tomatoes are banging
Otherwise you end up hopping between services that start out free, no strings attached and then turn to crap.
There’s more to the comparison than price.
But in this case if you don't agree with the price increase, as OP further justifies, I think it's totally fair to just go elsewhere.
> Replit changed its paid tiers by raising the price of my plan and removing some features.
That’s a healthy and fine market outcome. What was worth it before is now no longer worth it to some buyer. Neither the ex-buyer nor seller should be surprised or upset here, as the points of view of both are entirely rational.
1. Since you say it is an open market with alternatives, I don’t see why you seem to take issue with the blog post author taking one of the alternatives.
2. I thought the author did have some issues with the product. Like lack of persistence of uploaded files, price going up, and the support for the author’s current main language, Lisp, being not as good as for Python.
I don’t see how it’s a bait and switch to increase prices to a sustainable level if it wasn’t previously there. If you like a SaaS product you should hope their business model is aligned for durability exclusive of burning VC cash in my view.
If the product doesn’t meet your needs, fair game. Complain away it’s good feedback the vendor needs to hear to improve. Vote with your dollars like this author did.
Sure, but that doesn't make their actions not bait[ing you with a low price and lots of features] and switch[ing plans to remove some of those features and raise the price].
It's still a bait-and-switch move, IMO. You might choose to tolerate or accept it in the interests of the company being sustainable, making it a "bait and switch that you're OK with".
Since they have to maintain files and lisp support out of band, they're really not far off from running dev containers, which defeats the point of Replit.
Edit: clarity
Do I have a say on how they should/shouldn't invest their money? I imagined. So I can't really sympathize with points of views such as this. Are tech companies entitled to eternal growth?
Why shouldn't i switch to any other provider as soon as I'm unsatisfied with current one?
This seems like really really dumb line of thought that leaves you to be exploited by service providers. It's basically mental vendor lock-in.
It's up to service provider to find out the profitable business model, and you don't need to integrate deeply with such unprofitable service providers.
I think the best moral argument I can come up with is trust/loyalty and viewing it as a relationship, but that's not emotionally persuasive with large companies like we have in tech I think.
>>> why would I, an user, should care at all about anything that my service provider does internally?
I suggested, "morals".
In short, I responded to a question asked but you seemed mistakenly to think I was responding to the context in general.
In any case, let's go reductio ad absurdum, if your service provider employed child and/or slave labour then you may feel that enriching them with your custom was not appropriate.
There's a whole industry [0] devoted to choosing manufacturers according to their morals and socio-political positions; I thought the response was self-explanatory.
As far as paying a company that doesn't meet your needs any longer. I've done this when I approve of the company as a general source of good (benevolence). But only on a couple of occasions. I'm sure it's a very weak signal.
Yes, with large for profit companies I'm not going to do this. There is a situation where you might - to retain rights that are given to customers. Some people pay for the cheapest insurance to get access to discounts (UK) afforded to customers. There might be a situation where retaining customer rights was like having a company on retainer which probably comes into your trust/loyalty category.
Do not push 'morals' to the end user of service.
Make a system that enforces companies to not break them in the first place.
Maybe people get upset with higher prices paired with fewer features.
Or are you ok if food companies reduce the package content and raise the price at the same time?
It's for profit, you know?
In the absence of a source showing all of their financials, this isn't a particularly helpful comment. Beyond that, if they raise the price too much and go out of business, their customers are certainly not better off.
He doesn’t want the product at the current price. It’s a bad value for him.
You’re requiring the consumer to want management’s goal. But product survival is not a buyer’s goal. The buyer has limited money, and wants his own profitability.
It's also really good for teaching, and for sharing live-coded snipets and so on.
I have no idea about using it for actual production coding, and deploying from a repl, as I haven't tried it because it it looks far less suitable than a traditional development workflow.
But it seems like they've received some 'investment' that may be pushing them towards being an actual production tool. IMHO, this will cause them to lose their hobby, hacker, and education patrons, and still not win with serious professional, commercial ones.
I sometimes wish companies had „dumb“ plans where I could just pay less for the main product instead of the bolted on intelligence.
It is definitely a big jump in cost.
I use replit for my experimental projects when I just need a quick place to write some code to see how to do something. I use the git integration with GitHub which is really helpful.
I wouldn't want to set up Nix myself, but I appreciate that the "replit.nix" is easy to add packages that are necessary.
I am torn on what I'll do as I do see value in Replit and really like their product, but not sure I need it at $20/month.
Why not? Even the official installer is pretty straightforward, the biggest bottleneck that comes to mind is setting your flakes up with the right template. Even then... I don't think I spend more than 15 minutes a month editing or fixing my flakes. It feels more like a superpowered makefile than a roadblock; I recommend learning the ins-and-outs even if you intend to stick with hosted environments.
I am not at the point I have a mental model of what Nix really is that I have with git.
I understand it has something to do with derivations where each package is a collection of files at a given version and the data and state is immutable. Which reminds me of Git.
It's also a programming language for expressions which evaluate to a hierarchy of files on disk.
pkgs.git, pkgs.vim
I find the tooling, command line utilities aren't immediately understandable to me. I just rely on that Replit have implemented the Nix integration so that when you change "replit.nix" it just updates the environment :-)
I really ought to give an immutable desktop a go at some point such as Silverblue .
I built my own self-hosted Replit 'clone' for replicating that specific use case but under my control. I mapped a wildcard subdomain to my server and wrote a web IDE and backend using Docker's REST API and Openresty to spin up quick projects that are publicly accessible. It works really well for me, I haven't open sourced it because I don't know if anyone else would want it though.
I don't need that specific use case but I do love seeing the tricks folk do with Docker. Maybe all you have to share is a readme and compose yaml?
Let’s move programming entirely into an environment where you don’t own your data, can’t duplicate or fully understand the runtime, are subject to total surveillance and the harvesting of your data for AI training and other monetization, and must pay rent forever with the constant threat of a rug pull. Great idea.
The thing I find most dystopian about it is that it’s aimed at beginners in a lot of ways. So you could have a generation raised up that doesn’t understand the idea of general purpose compute under their own control at all. Basically it’s the last nail in the coffin of personal computing.
But VMs can abstract away most of this, especially in a learning environment where performance isn't a primary goal.
Then you can have a known-good set of instructions that doesn't have to include messing with whatever Apple/Microsoft/Ubuntu changed recently.
Learning to paper over OS errata isn't as generally useful as, say, groking multithreaded coding models.
Yes, there are environment quirks. Yes, you'll have to deal with them. Yes, you can look up documentation when you run into those situations.
I hate setting up environments, even with a folder of templates I've assembled over the years. The most frustrating barrier to get to the "magic" of seeing something happen is figuring out the proper/correct way to structure a project.
Towards the end of intro courses seems like an appropriate time to start bringing up tooling.
they donate a couple of thousand dollars and in return get a CS class that will go out into the world completely dependent on them
Why are beginners using it?
Why are people using it?
And how could we solve those problems or recreate that experience in a more free form?
2) The market demand for dramatically more accessible software development tools (more economical product development) is essentially unbounded
3) Replit has produced a marginal change in the frontier of accessibility, at unknown unit economics
4) What would a discontinuous change (step change) in accessibility look like?
Side note, ZIRP and AI have really muddied the waters here. ZIRP means we still don't know yet which companies are zombies. The AI claim is that product development will soon be decoupled from the economics of human coding. Neither of these issues are likely to be conclusively resolved for another few years (we can all place our own bets). Replit is deeply rooted in both.
Now it's likely more "What is your growth efficiency (dollar:growth) in a capital-constrained environment?"
And we're going to see more and more capital sucked back into debt service, as financing comes due and is reestablished. Which will snowball the terms for any companies which require capital infusion ASAP.
It'll be curious if the Berkshire Hathaway model of coupling low-growth, good cash-flow businesses to high-growth, bad cash-flow engines becomes dominantly competitive again.
I'm not actually familiar with the issues that VSCode has but I seem to recall some key component was not OSS, but I forget the details there and maybe it has changed. I know it has telemetry and such, but AFAICT that can be disabled by some settings. (I personally use vscode for my own work and disable telemetry and don't use any code assistant platforms, and I would like to know if there is a problem with what I'm doing)
IOW, frog being boiled slowly.
I have a friend who got a fine arts degree in college and has spent the last several years working crappy odd jobs to make ends meet, and finally came to me earlier this year and said she wants to learn to be a web developer. I got her set up learning JavaScript in all of 10 minutes using Replit, and frankly it was exactly what I would hope for pedagogically. It's free for our purposes, dirt simple to set up, and has enough features to be helpful without being overwhelming.
We've gotten to a point now where we're introducing HTML and CSS and building real websites (after about 3 months of JS intensive) and I decided this was the right time to introduce coding locally rather than in Replit. She's a computer savvy person and was able to stumble her way through it in a couple of hours (she didn't want my help as this is how she learns stuff) but I can tell that the need to manage a locally running environment slows her down. This is a good thing in the long run of course, and I think pedagogically there's analogues to this in many disciplines (in learning piano, for example, moving from simple drills and method books for learners to "real" music feels as significant a leap), but the step function in complexity to do simple tasks is certainly there. It's important to jump that hurdle, but forcing it too early can discourage early learning and cause you to focus on the wrong things.
I had her shadow me working on a side project early on in her studies so she could see what the whole process looks like, and the sheer number of tools I was jumping between to do my work (AWS, Vim, the terminal, database query console, developer tools) was overwhelming. Replit allows you to focus on only the most important parts of the theory of programming, which is absolutely essential when starting out if you aren't immediately predisposed to doing complicated stuff on your computer. I think it adds a lot of value, so long as it's used responsibly in the context of a larger curriculum.
The goal of personal computing was to make computers, with all their power, available to everyone. In that Replit is much more of a continuation of that work than its antagonist.
I could see everything you do being monitored for the implementation of unauthorized types of software for example, not to mention total surveillance and appropriation of everything you do.
“We’re sorry but it appears that the software you are implementing might be able to be used to facilitate communication without the required safeguards. Your project has been locked.”
Meanwhile if the center of gravity goes entirely to managed cloud services the endpoint will wither even more. I can see a future where you can’t even buy a general purpose computer except in the most raw form like SBCs or parts and doing so might even get you on a list.
Look at the EU chat control stuff or the crazies who want to ban matrix math. This is not that far fetched.
They’re focusing on AI capabilities at the core of the product, because they believe that’s the future of software development. It’s admirable that they can make such clear decisions rather than waffle in an attempt to make everyone happy
Focus = Speed. Focus means saying no to the good to focus on the great
But I have always been on the free plan. Their paid plans are indeed very expensive for what they offer.
That being said, I did setup a codespace for a one click to try a new feature product and that was very cool.
Clone the repo, open in container, complete toolchain with all the extensions and settings you’ll need. I absolutely love it.
I would suggest trying JavaScript. Its functional programming support is much better than Python’s, and it is widely supported.
Additionally python with a type checker supports sum types AND exhaustive pattern matching similar to haskell and rust.
Typescript does not support this as far as I know. Outside of types the differences between the two languages are just sugar.
Lisp on the other hand is something truly different.
One thing I always miss in languages like Python and JS is the identity function. I don't how people are writing all this functional code without it.
lambda functions in python have as much expressive power as any function.
>comprehensions things feel messy without the ability to pipe previous results to a next function
compose :: (a -> b) -> (b -> c) -> (a -> c)
is definable in python Along with type checking. This is basically your pipe operator. Python has very much the capability to come rather close, closer than javascript to the flavor of functional programming found in ML languages like haskell.The benefit of using python is that you can cheat a lot too which is more challenging to do in language as strict as haskell.
Here:
from typing import Callable, TypeVar, List, Any
from numbers import Number
A = TypeVar("A")
B = TypeVar("C")
C = TypeVar("C")
def compose(f: Callable[[A], B], g: Callable[[B], C]) -> Callable[[A], C]:
return lambda x: g(f(x))
def curry(f: Callable[[Any, ...], Any], x: Any) -> Callable[[Any, ...], Any]:
return lambda *args: f(x, *args)
def compose_many(fs: tuple[Callable[[Any], Any], ...]) -> Callable[[Any], Any]:
return (lambda x: x) if len(fs) == 0 else fs[0] if len(fs) == 1 else compose(compose(fs[0], fs[1]), compose_many(*fs[2:]))
MultAllType = Callable[[List[Number], Number], List[Number]]
multAll: MultAllType = lambda x, y: [i * y for i in x]
SubTractAllType = Callable[[List[Number], Number], List[Number]]
subtractAll: SubTractAllType = lambda x, y: [i - y for i in x]
quadrupleAndSubtractTwoFromAll = compose_many(
curry(multAll, 2),
curry(multAll, 2),
curry(subtractAll, 2))
as literals: quadrupleAndSubtractTwoFromAll = compose_many(
lambda x: [i * 2 for i in x],
lambda x: [i * 2 for i in x],
lambda x: [i - 2 for i in x])
Python gets a bad rep for being noob language but it's capable of functional programming with very very good type checking. You can cheat too and go no types like lisp as I've shown in the example above.Overall I would say it's superior to typescript in terms of functional programming due to exhaustive pattern matching (which I did not demonstrate above.)
In terms of FP in python versus FP in lisp it's mostly just opinionated differences. Python and lisp sort of even out because python has optional type checking and lisp has macros. I would say though that python leans more towards the ML flavor of FP which makes it less comparable to lisp. Apples and Oranges.
The example is interesting. Here's how I might have done something similar in JavaScript. Currying is part of the JavaScript language, and I composed a list of curried functions using reduce.
const multiply = a => b => a * b
const subtract = b => a => a - b
const quadrupleAndSubtractTwo = a => [multiply(2), multiply(2), subtract(2)].reduce((x, f) => f(x), a)
const quadrupleAndSubtractTwoFromAll = numbers => numbers.map(quadrupleAndSubtractTwo)
> quadrupleAndSubtractTwoFromAll([3, 4, 5, 6, 7])
> [ 10, 14, 18, 22, 26 ]Reduce map are all available in python as well. Basically your implementation is doable in python as well with the same level of tenseness. The main difference as I said earlier is typescript lacks exhaustive pattern matching and sum types.
const compose = (...functions) => a => functions.reduce((x, f) => f(x), a)
const quadrupleAndSubtractTwo = compose(multiply(2), multiply(2), subtract(2))But anyway no point in this. Python can match the terseness of JavaScript.
The only reason my implementation was long was because I used types and recursion. Python can have the same terseness as your old style untyped javascript if needed:
compose = lambda fs: (lambda x: reduce(lambda acc, f: f(acc), fs, x))
quadrupleAndSubtractTwo = compose(multiply(2), multiply(2), subtract(2))
remember the reduce function can be built out of recursion. What you see in JS is just a convenience function for reduce, if a language has recursion, reduce can easily be built in one line. def reduce(f, xs, x):
return x if len(xs) == 0 else reduce(f, xs[1:], f(xs[0], x))
Thus reduce isn't really a "feature".Python is superior to JS for FP because it can match the expressiveness of JS while adding the additional feature of exhaustive pattern matching and list comprehensions, which JS or TS can't do. This makes JS explicitly inferior.
First of all the discussion at hand is not the language implementation, the discussion at hand is about the language specification. TCO is a implementation feature, whether the engine/compiler/interpreter implements said feature is irrelevant to the conversation which is about the specification NOT the implementation. So on this count you are wrong. More accurately off topic.
Second there are several python interpreters. The most popular is CPython. CPython does not include TCO deliberately because Guido specified he wanted stack traces at all times for easier debugging. However PYPY which uses a JIT does use TCO. Stackless python another interpreter by it's very name also does something very similar to TCO. So additionally you are completely wrong again from this angle.
Third there are two popular JavaScript engines in use by browsers and nodejs today. V8 and spider monkey. Spider monkey Does not implement TCO. V8 Did implement TCO for a small amount of time, however, this was later removed due to complexities when debugging practical issues. Thus V8/Spidermonkey and therefore Nodejs and Chrome and Firefox do NOT support TCO. Edge supported TCO with chakra but after a shift to V8 edge also no longer supports TCO. So on this count you are wrong again.
Overall to sum up everything here, you are just wrong, wrong, wrong.
The statement still stands, as a language specification python is more superior feature-wise for FP then JS or TS.
TCO is in the ECMAScript specification. See: https://262.ecma-international.org/14.0/#sec-preparefortailc....
Your composition and curry are OK, and related tools exist in standard libraries. The lack of a first class support is a minor annoyance but not a showstopper, and the solutions are not as natural as genuine pipe notation (you can’t simply write left to right and generate text autoregressively). The lambda limit was more real in my mind and I hope Python eventually corrects it.
That is literally the definition of FP. That the definition of a functions be a singular statement as opposed to a procedural function is a function made up of several statements where each statement has the potential to assign or reassign values. If you write a function with procedures you are not doing functional programming. That's why python lambdas are defined that way.
That being said python doesn't support the let...in expression which is common to do in fp, but neither does JavaScript.
JavaScript just supports anonymous functions that aren't functional. If you make the procedures const then you get something similar to let in which is arguably a trick to make it work.
You can do tricks in python to achieve the same thing with lambdas. In JavaScript you do tricks to make anonymous functions behave like lambdas with let-in, in python you can also do a trick to get let-in behavior in a lambda.
f = lambda x:(
y := 1,
w := 3,
y + w + x)[-1]
Arguably though you shouldn't do this. The pythonic philosophy is that Any function past a certain level of complexity you should just use def rather then inline it. This philosophy still applies in FP.Ultimately these are minor syntactic and stylistic differences involving trivial sugar.
I don't think python will "correct it" because from their perspective there is nothing to correct. Make your function a def. That's the pythonic way.
The first class support for for pipe operators and what not are not present in JavaScript or python. It's not showstoppers. But in python it is possible to get composition working with magic method operating overloading. It's just not first class.
Fp in js never involved the algebraic operator style promoted by haskell. In this sense it's more lisp style and python is similar to js in this respect.
> lambda functions in python have as much expressive power as any function.
There is no fundamental reason why Python doesn’t have let, and there is no fundamental reason to not be able to catch exceptions within a lambda. Python already fixed the unneeded print statement in its history so I think there is hope. (I don’t think js is relevant here; I was trying to explain why lispers or people who like Haskell may revisit their improved expressive environments).
In traditional languages programs are a list of procedures that change and mutate state.
A list comprehension is functional in every way as it is a single expression. It does not change state. It is functionally equivalent to map and filter and even flatmap.
If you need an official source you just need to know that list comprehensions are borrowed from haskell. That's where the term came from and that's where the feature was borrowed from.
> I value readability and usefulness for real code. There are some places where map() and filter() make sense, and for other places Python has list comprehensions. I ended up hating reduce() because it was almost exclusively used (a) to implement sum(), or (b) to write unreadable code.
https://developers.slashdot.org/story/13/08/25/2115204/inter...
Also, comprehensions are inspired by set-builder notation.
The benefits of functional programming are less technical debt and greater modularity and less bugs.
The cost is less readability and less efficiency.
Reduce is ultimately the most readable way to iterate and accumulate with FP. The only other way would be recursion which is less readable.
Overall, still love Replit, just unsure if I'll continue paying myself. Not because it's bad, but because I don't' necessarily need it.
> Lisp is the language that comes most natural to me, I'm most productive with, and gives me joy and not just fun
Can you elaborate on why please? It feels relevant to this article.
For example, I can say in Lisp it's easier for me to start writing and evolving programs which in turn allows me to produce more code than in other languages. As for the joy, it comes in part from the instant gratification of a low friction environment where you can evaluate -- and see running -- anything from an individual atom to a full program.
Part of this is that Replit is for people who want to get things done, but are intimidated by JetBrains's IDEs. Lisp is a language nerd's language. So really, you're not the target customer.
> chromeOS lifestyle
Maybe I'm out-of-touch, but I assumed Lisp hackers would be on something beefier. Yes, it's a "linux" laptop, but it'll be an uphill battle. I expected either a Linux Thinkpad or Framework, maybe Mac OS on a Macbook.
I actually looked into ChromeOS for my grandma. She basically just browses the web, uses gmail, and plays Freecell, but the app situation made Freecell a non-starter.
He’s using an “Intel CORE i7 ASUS Chromebox 3 with 16 GB RAM and 256 GB storage”.
https://journal.paoloamoroso.com/why-i-use-a-chromebox
Previously discussed here, oddly enough:
> realized I was living in Chrome anyway
For average users, this fine, but for software development, I'd find it too limiting.
I completely empathize with the hassle of maintaining a linux desktop. I use Windows for this reason. Servers are another story.