Maybe you should gift her with a newer pasta machine. :)
Pasta certainly isn't a staple of Finnish cuisine, but through family I have Italian relatives, and my parents have been making handmade pasta since before durum wheat was widely available here (it certainly was a very different world back then). Their hand cranked pasta machine has among other “heads” a tool for ravioli, taking in two sheets of pasta dough and automatically applying contents for each one it cuts. Certainly faster than filling them one by one, can't tell if you can taste the difference. (I really used to like pasta, shame that certain grains and I don't get well together.)
Ubuntu has done that a long time if there's a problem with graphics drivers. Don't know more specifics for your issue, since I haven't run Ubuntu in a VM in years.
You do. But keep in mind they have way less parts, moving or otherwise. Spark plugs, cables, the entire engine cooling system, fuel pumps, all of that is missing.
It boils down to: battery (big unknown, but seem to be holding up surprisingly well), engine (incredibly simple!), no transmission or a very simple one (Nissan Leaf has a single gear), inverter, charger, brakes, and the standard 12V battery you find in all cars (which doesn't have to drive a starter motor, so should last longer).
Wow, electirc cars are so simple it is surprising that so few companies make them! The moving parts in a car are pieces that 1) have multiple manufacturers and are relatively cheap to replace, and 2) can be replaced by a wide range of repair shops so that competition can keep a check on the overall replacement costs. What you left out of your electric car list are all of the specialized electronics and only-for-this-car equipment that are all very expensive to replace and will all only be supplied by the manufacturer. The idea that you can just go online and shop around for an inverter for your Tesla or run down to the auto parts store to pick up the right 12V battery is laughable.
False comparison. Your gas car also has specialized electronics, namely the ECU, the ABS system, the SRS system, which are all needed for the car to be operational. Good luck finding an aftermarket ECU for your car.
There's no more "only-for-this-car" equipment in an EV than in any other car; the main difference is that with so many models of gas cars made by each maker, they reuse a lot of parts between models, so there's economies of scale. In an EV future, the same would be true for EVs. You're not going to swap an axle from a Chevy into a Honda, or from a Honda Civic into a Honda Ridgeline, so even here it's limited. And you're not going to swap a door panel from a 2017 Civic into any other car at all, or from any other car into that one; those are only-for-this-car items; every car has those.
There are lots of aftermarket ECUs [1]. Usually only performance tuners buy them, but there's no reason you couldn't get one for other reasons. That said a junkyard ECU is going to be a much easier fix.
Your aftermarket ECU won't pass emissions tests in most places that have them, so this really doesn't exist for practical purposes. Aftermarket ECUs are for race cars.
As for the junkyard ECU, why do you think that won't be also true for EVs?
>You can usually choose different maps with aftermarket ECUs, there's no reason you couldn't load one that passes emissions tests.
Will it look exactly like the factory ECU? Most emissions tests now consist of plugging in a device into the OBD-II jack and ensuring the factory emissions equipment has not been tampered with. An aftermarket ECU would fail this; it's "tampering" by definition. Emissions laws generally do no allow any deviation from factory spec or factory equipment. They don't just test the actual emissions levels, and they don't test the levels at all in many places.
>Anyway, this is a stupid argument, I hardly think that emissions tests will be a reason you can't put an aftermarket ECU into an electric car!
It is stupid, because that's not what I claimed at all. One poster claimed that EVs would be too expensive to fix because of non-standard, "only-for-this-car" electronics. I pointed out that this is already true for gasoline cars, with ECUs being an example. Then someone else jumped in and claimed that aftermarket ECUs exist, when in reality they're horribly expensive and only racecars use them, so that claim was irrelevant, and then they admitted that you can just buy a junkyard ECU cheap. I pointed out that this would also be true of EVs, which was just ignored, even though it completely invalidates the argument about EVs being expensive to fix.
Face it: every car has specialized parts, especially electronics. You can't just take an ABS module from a Nissan and slap it into a Ford. You can't take a wheel bearing from an H2 and slap it into a Prius. Parts for mass-market cars have always been available from different places: dealerships for OEM parts at high prices, aftermarket parts for popular models from parts stores, junkyard parts for everything if you can find them and are OK with them being used. This will be no different for EVs; it's stupid to think it would be. And it's also stupid that several different people jumped in here with completely incoherent arguments, all so they could bash EVs.
Yes this whole ECU thread has nothing to do with the original discussion comparing EV and gasoline vehicles wrt how easy it is to get replacement parts.
>> I hardly think that emissions tests will be a reason you can't put an aftermarket ECU into an electric car!
> It is stupid, because that's not what I claimed at all.
Yes you did:
> Your aftermarket ECU won't pass emissions tests
You brought up aftermarket ECUs not passing emissions tests, I just (incorrectly) commented that you could probably load a stock (or what I thought would be emissions-passing) map onto an aftermarket ECU because I wasn't aware about the tampering part. I naively assumed they actually tested the emissions from the car when testing it for emissions. :P
For what it's worth, I agree with you about replacement parts being specialized for all types of cars, and for the record I'd be very surprised if an aftermarket ECU ever appeared for the Tesla, given how closed and hostile to any modification (or even repairs!) they are. You can't even get a service manual if you don't live in Massachusetts, and even then you can only buy access to it on a subscription basis! [1]
In fact, at the moment I'd never even consider buying a Tesla because who knows what it's like to own one after the warranty is up? If my Tesla ECU failed, there's nothing to say it would even be possible to put a legitimate Tesla junkyard ECU in there and have it work without their blessing.
Out of curiosity, do places that have emissions testing actually keep testing cars regularly every year?
> You do. But keep in mind they have way less parts, moving or otherwise. Spark plugs, cables, the entire engine cooling system, fuel pumps, all of that is missing.
My hybrid actually has two independent liquid cooling circuits: one for the ICE, one for the electronics.
But other than that nit, I agree with your argument.
What if you just want to view the contents of input-file, unpaged. `<input-file` doesn't print anything unfortunately (curiously it doesn't error either).
I guess I'm never to actually “get Lisp” to appreciate its syntax.
>Aside from the prefix ordering, Common Lisp’s syntax is already a bit more elegant because you can set arbitrarily many variables without repeating the assignment operator over and over again:
; Have to type out `=` three times
x = 10
y = 20
z = 30
; But only one `setf` required
(setf x 10
y 20
z 30)
I utterly fail to see the aforementioned elegance, although I certainly can't miss the line where it happens.
So do I. I prefer to type out `=` three times, for a simple reason: while not being more verbose than the `setf` example (3 additional tokens in both examples), it makes all 3 lines the same, which is more regular.
We could make all 3 lines the same with `setf`, but that would be a bit more verbose:
(setf x 10)
(setf y 20)
(setf z 30)
In a program that heavily use the assignment statement, I vote for the shorter form, `=`.
It is absolutely more verbose. The Lisp form can store N constants into N variables in 2N+3 tokens: two parentheses, plus the variables and constants and one symbol. Assignment statements require 3N tokens: N vars, N constants, N assignment operators. That's assuming they don't need some mandatory separator or terminator like a semicolon. We break even when N = 3. For N > 3, 2N+3 < 3N.
Anyway, this is hardly the main point of the article (and probably detracts from it).
Indeed, my main point is not verbosity —it's regularity. I'd rather repeat `setf` in most cases in the name of regularity. That way we spot the semantic difference between lines more easily.
You'd have to use the assignment heavily to justify implementing the `=` syntax, which is barely prettier than the regular `setf` syntax. Plus, you'd probably have to add some annotation anyway, partially defeating the point:
I'm not much for Common Lisp, but I do think Scheme is the prettiest language in which people write ugly code. As such, while I am sympathetic to the virtues of s-expressions, this example is not going to win any hearts or minds. I don't much care for Python's performance or newer features, but your snippet screams for a comparison:
if condition:
a, b, c = c, a, b
a, c, b = b, a, c
That really seems much more clear than the gymnastics my mind has to do manually pairing the assignments inside of psetf. I won't argue that it's objectively better syntax, but I still think it is.
Mind, I haven't tested this, because I don't have CHICKEN Scheme (the dialect this is written in) in front of me, and I may not have matched all the parens on the end, but it should work like this:
(assign-group! (a b c) (c a b))
Giving you your nice assigment syntax you wanted.
That's the nice thing about Lisps: if you don't like it, you can change it.
There is in fact one error in the above macro: well, I think only one: in the map, (lambda (var val) '(var val)) should be (lambda (var val) (list var val))
That is why you would typically create a struct, and then assign the whole struct at once. If you are regularly assigning > 20 variables at the same time, something is wrong with the language you are using.
on the other hand = is one character, and if it's not a legal character in identifiers then
x=1 y=2 z=3 takes 2n characters (setf x 1 y 2 z 3) takes 2n+7 characters (plus however many we're using for the actual identifies and values but those'll be the same between examples)
Lisp has an = function; so that binding is taken. Symbols in the keyword package are allowed to have function bindings, and so a synonym for setf can be called := (the symbol named "=" in the keyword package).
[1]> (defmacro := (&rest args) `(setf ,@args))
:=
[2]> (defvar a)
A
[3]> (:= a 42)
42
[4]> a
42
[5]> (= a 42)
T
Having programmed many substantial projects in both worlds, I have to admit that I much prefer S-expressions over any other syntax -- without complicated macros that introduce some sort of keywords or other tricks. With S-expressions, there is basically just one syntax to learn for every construct, so you can focus on the semantics. (I do prefer Scheme's way of dealing with functions, but that's another matter, of course.)
Unfortunately, I otherwise prefer strongly typed systems languages with a strong focus on compile-time, zero cost solutions such as Ada or Rust. My ideal language would be a very fast, statically and strictly typed language with a modern incremental garbage collector that can be switched off and without type inference, but with an S-expression syntax.
However, if such a language existed or I'd develop it on my own, it probably wouldn't gain much popularity... ;-)
> although I certainly can't miss the line where it happens.
Consider the following for many C-style languages:
if (a = b) { a = a + 1; };
If there is any goodness in the world, I'll never write/fix another of these bugs again. This is the only reason languages have an '==' operator.
In many LISPs this type of bug is practically impossible to implement accidentally.
(if (= a b) (incf a)) ; This form, by itself, can't assign b to a.
To recreate the bug as before, I would mangle the statement or have explicit declarations outside the conditional block.
(if (progn (setf a b) (= a b)) (incf a))) ; uh, maybe? Does it even compile? I don't know how to computer.
(setf a b)
(if (= a b) (incf a)) ; more likely, but 'setf' would raise flags and the if statement itself isn't doing the mutating.
Clojure makes this even harder because of it's immutability by default.
(let [a b] ; statement must enclose 'if' block, which would be a red flag.
(if (= a b) (inc a)) ; technically I can't 'change' anything here w/o the mutation primitives.
(if (let [a b] (= a b)) (inc a)) ; mutate in conditional, but the 'a' doesn't change outside the block,
; and now you have two bugs.
(if true (let [a b] (inc a))) ; Mimics the bug from the top, but the statement is mangled beyond comprehension.
There are many languages that use = for assignment and == for comparison, without the possibility of confusing the two. In Python, for example, assignment is not an operator at all, so using it in expression context is invalid.
Which leaves the distinction between assignment and comparison - which is always there - as the only reason to have two distinct operators. Which ones they are becomes a matter of taste, but as I recall, the reason why C settled on = for assignment is because it's that much more common. This is still the case today, even in pure languages where it's used for bindings only.
Math notation uses := for assignment and = for equality, no? So in that sense Algol and the Pascal family are more consistent with that, while C actually diverged.
Depends on your field. Some math subjects would argue that "assignment" does not exist, because the same name within the same scope always refers to the same value, whether it's known or not.
Within algorithms, I'm most used to "<-" for assignment, for example "i <- i + 1" inside a loop to count iterations.
I'd argue that anything unfamiliar is harder to read because your brain had trouble picking out the signal, and this is not a real problem with the language.
I sat down for a month and a half and just did Racket every day. It was a very good experience, in that I learned a lot about programming in general (Racket's OO constructs are particularly good).
These little syntax tricks aren't the point of the SExpr languages. I think beginners tend to get caught up in them, but they don't actually affect the ergonomics of the language that much and end up becoming transparent to the programmer. Translating Python to Racket is a fairly trivial process, for example.
The point of them is that they are infinitely composable, specifically programmatically. The emphasis is more on writing programs that generate themselves. Think of it like making it trivial to make your own opinionated framework on the fly that costs nothing at runtime.
In Racket, things like File IO vs Network IO can be abstracted to the same exact interface. You might use such a thing to write web services that you can test using saved sessions, and it's fairly easy to do. There is some misconception that Racket is missing a lot of libraries that I don't think is quite as bad as people think because a lot of the things you would need a library or framework for in other languages are ready enough to do on your own with a well thought out macro.
I agree that the former is more elegant in that the syntax is helping more.
But LISPers prefer the latter, because its elegance is that it's a single expression, and the same sort of expression as everything else. Which makes it easier to extend, compose, manipulate, etc. That's the tradeoff of LISP's syntax--you get extreme flexibility and customizability, at the expense of being constrained by its syntactic simplicity.
I agree. This is one of the least compelling Lisp things I've ever read - because, aethestically, I really dislike Lisp. From a design standpoint, I want to love it. The elegance of S-expressions and the simplicity of it all call to me! But in practice its just too ugly!
If the projects GitHub page is anything to go by, I doubt that. The only thing that's been changed in 9 months is the readme, and the change was to remove the note about the project being in "active early development".
Best would be a model where a persistent process handles multiple requests concurrently, but that is not normal for PHP. So you need to make sure that all the libraries you are using are not leaking, have a nice db connection pool, and write a PHP framework that handles concurrency. Might as well use a better language at that point :-)
> This means that there is a conflict between performance and having a well structured object oriented framework.
What do you need a 'well structured object oriented framework' for? You're going to build up a huge object graph in memory, to output some HTML, and then throw away all the objects at the end of the request. Nobody is going to see your beautiful object tree, so don't bother. A blog entry page should be super simple.
Header and footer are dead simple echos of the boilerplate, maybe replace in the html title or something. Read the title and content from disk[1]. Have another data file for all your articles for the index page.
I prefer not to have comments on my blog, but if you must, you can put them in a database; limit to something like 100 or 1000 comments per article (because really) and limit threading, and it's going to be pretty quick to query them (make sure your webserver is doing reads from a database in the same metro area, if not on the same box).
Recent comments is across all blog entries; I would probably add a index on the time in the comments table and just select 2 from there; you could union that into the earlier comments query if you don't want to make two round trips to the database.
You don't need to do this with concurrency, each page load has barely anything to wait for, so more threads doesn't help throughput. Run enough php workers (php-fpm, or apache children if you're using apache_mod_php) to keep your cpu busy, and you're golden.
[1] There's four articles on this blog -- it doesn't need a database. PS run php as a user that can't write anywhere on the disk, and push the blog entries and the summary datafile with another user.
Edit to add: If you skip comments (or outsource to disqus or some other comments w/ javascript platform), you can make the whole site just static html, and leave PHP at home. OTOH, these guys are running Wordpress, because they like frequent security updates?
> The performance issue comes with loading source files on every request
PHP ships with an opcode cache built-in (and at least on every distro I've seen, enabled by default) since PHP 5.5 that keeps the compiled bytecode in shared memory
In my experience php is fast enough until you start generating lots of garbage. It seems it wasn't really designed to garbage collect at all, but to rely on the per-request cleanup.
We should really stop pretending that the garbage collector is the problem with langauges. The collector isn't the problem, your garbage is the problem.
[Not that I'm a proponent of PHP, though it does make popping shells far more fun.]
The code becomes kind of weird when you have to second guess the language.
Now, the approach PHP takes is fine for the original vision of the language. It even works great.
But languages designed for long running processes often have some sort of mechanism for dealing with that situation explicitly. Like the `NSAutoreleasePool` in Objective C. In C++ you might build your own custom slab allocator.
I'd say the garbage collector is one of the problems with PHP. Then again, if you run into it, PHP might not be the right tool for that particular job.
It depends on the code base and use case. For the vast majority of coders, the time/cost savings will be in the usability of the language itself rather than the hardware required to run the code.
Pasta certainly isn't a staple of Finnish cuisine, but through family I have Italian relatives, and my parents have been making handmade pasta since before durum wheat was widely available here (it certainly was a very different world back then). Their hand cranked pasta machine has among other “heads” a tool for ravioli, taking in two sheets of pasta dough and automatically applying contents for each one it cuts. Certainly faster than filling them one by one, can't tell if you can taste the difference. (I really used to like pasta, shame that certain grains and I don't get well together.)