In short, I think there are very clear and tangible things that give software estimates a meaningfully higher uncertainty than other engineering disciplines.
3,114 karma · joined October 20, 2007
In short, I think there are very clear and tangible things that give software estimates a meaningfully higher uncertainty than other engineering disciplines.
Of course I don't have any scientific evidence for this claim. But there are lots of phenomena that exist in the world that don't yet have scientific support. I think that software his higher uncertainty because it is much less constrained than physical engineering. There are a relatively limited number of ways that one part of a physical system can impact other parts, and those are constrained by the laws of physics. Software systems have no such laws. It's often possible for any component to write to arbitrary locations in memory controlled by any other component. This is kind of like a rusty hinge on a 34th floor bathroom door causing a problem with a doorbell on the third floor. Those kinds of actions at afar just don't happen in the physical world and if they do, they happen via pretty well understood physical mechanisms. To make matters worse, the discipline of software engineering is less than a hundred years old as opposed to thousands of years for physical engineering.
It's not about feeling special. I think there is something fundamentally different about software.
You might watch a grandmaster chess game and think that you could make those moves. Or perhaps you see a solution to a traveling salesman decision problem and think "it's easy to see there exists a path that short". But in both cases you're mistaken. The moves you would have played wouldn't be as good as the grandmaster's. The path you would find wouldn't be as short. And the paint splotches you would throw on the canvas wouldn't look as compelling.
Yes, there does exist shitty "art"--things that you or your 5 year old could have done. But I suspect it's less common than you think.
Kadena is looking to fill a variety of roles to build next generation blockchain technologies. The software is primarily Haskell, but we are also looking for project managers, frontend developers, designers, etc.
* It makes it trivial to have multiple versions of the same package installed at the same time and allows you to switch between them at will.
* It is trivial to roll back your system after a failed upgrade. Difficult system recovers after you upgrade to a new unstable version are a thing of the past.
* Non-privileged users can install software completely securely.
* Projects packaged with nix have the best possible build reproducibility because nix accounts for ALL of your dependencies all the way down to the lowest level system libraries, compilers, etc.
Check out http://takt.com/careers for more information. Here is the DevOps Engineer job description:
Takt is seeking DevOps Engineers to support the development of our flagship product. Our platform learns and adapts to people's preferences, habits, and feedback—orchestrating highly relevant experiences that are truly unique to each person. Our vision will change the way people engage with their favorite brands across multiple industries, be it retail, finance, or healthcare.
As one of the first DevOps Engineers at Takt, you will be able to contribute to a large scale environment and an early stage infrastructure in addition to influencing our culture and processes which we operate. You will capture the entire stack as code and provide tools and solutions that facilitate the release, maintenance, and monitoring of the platform. You will be working on a cross-functional team and collaborating closely with Engineers, Data Scientists, and Product Managers. As an early member of the DevOps team, you will help us build a culture and practice that leads improved product quality, cohesive collaboration, and integration between Operation and Development.
I'm less concerned about the theoretical limitations of types that you seem to be talking about and more interested in looking at concrete real-world applications where you think you need dynamic types and seeing exactly what we can do to address them with a type system. I know there exist things that are difficult or maybe impossible to define types for (the Y combinator for instance, or possibly this assoc-in). My argument is that you don't need this power. I don't care whether difficult to type things exist, I care about whether real-world problems require them. I have yet to encounter one that I felt requires the same amount of dynamic typing power that you seem to be arguing for.
See this thread for some concrete examples:
https://www.reddit.com/r/haskell/comments/792nl4/clojure_vs_...
No. I'm proposing something like what tel described elsewhere in the thread. If that's not dynamic enough for you, then you can go with something like JSON's Value type. In both cases lenses give you very convenient and composable access and manipulation.
> I've always thought the function was trivial. I mean, it's just four lines of code:
But you have to read the code. The type signature / code boundary is very useful for allowing you to chunk things and abstract over implementation details. This particular case may not be much code to read, but that is often not true in the general case.
> Sure, but you have to write the type signatures, too. Type inference certainly cuts down on a lot of work, but it doesn't entirely eliminate the need for explicit typing.
> I also tend to prefer adding explicit type signatures, even for functions that could be inferred. It makes type errors easier to catch.
That's exactly my point. Type signatures can be inferred, specs cannot. Choosing to add them is irrelevant. If you want the add them that can be done automatically.
That's why I'm not trying to make it typed. Instead of
Map a (Map b c)
I'm dropping down to something like Map Int (Map Text a)
Map Int (Map Text Text)
[Map Text Text]
Vector (Map Text Text)
...which is more like what's really going on in Clojure.Come to think about it, assoc-in is a great example of why I want static types. It's very hard to figure out what that function does from reading the documentation. There's no type signature to help me, the description doesn't give me much more to go on. Reading the examples leaves me wondering whether I actually understand what it's doing or if I'm missing some corner case.
> it will generate and run tests for all functions that have specs
But you have to write the specs. And that's the code I'm talking about. Fundamentally the generator can't just know what behavior you want and what you don't want. You have to tell it.
No, it's just a simple [Map Text Text]. Or if you want a little more safety, then [Map Text Value].
> you can get an good approximation of correctness with runtime specs coupled with test generation.
But this requires more code. More code is error-prone and takes time to write and maintain.
This is not a hard function to write in Haskell. You make it operate on a list of maps, which is what the Clojure one is doing too.
> You don't necessarily need static typing to give functions some form of type signature or specification.
But you do have to have static typing to make sure those signatures are automatically verified to be coherent.
It seems like you're thinking about my statement from a turing-complete computable point of view. But I meant it from the point of view of what the compiler can do for you. It's not what things you can compute, but what things will be automatically checked.
I would say that for the most part, a statically typed language can do the same things a dynamic language can do, but not the other way around. Another commenter mentions the Any type, but I don't think that's it. It's maps. Rich wants to be able to combine maps with a union operation, take subsets of keys, etc. And that is exactly what maps afford. I'd rather work in a language like Haskell where I can use strong types when I need them and drop down to untyped maps when I need them than a language like Clojure where all I ever have is the maps.
Another thing static types do for you is that they make things in your application more discoverable. Instead of tracing through to figure out which data is available and operations something supports, the compiler tells you. I'd rather work in a language where my compiler can help me this way than in one where it can't.
Check out http://takt.com/careers for more information. Here is the DevOps Engineer job description:
Takt is seeking DevOps Engineers to support the development of our flagship product. Our platform learns and adapts to people's preferences, habits, and feedback—orchestrating highly relevant experiences that are truly unique to each person. Our vision will change the way people engage with their favorite brands across multiple industries, be it retail, finance, or healthcare.
As one of the first DevOps Engineers at Takt, you will be able to contribute to a large scale environment and an early stage infrastructure in addition to influencing our culture and processes which we operate. You will capture the entire stack as code and provide tools and solutions that facilitate the release, maintenance, and monitoring of the platform. You will be working on a cross-functional team and collaborating closely with Engineers, Data Scientists, and Product Managers. As an early member of the DevOps team, you will help us build a culture and practice that leads improved product quality, cohesive collaboration, and integration between Operation and Development.
Lists under concatenation Booleans under AND Booleans under OR Numbers under max Numbers under min
In code:
smash :: Monoid a => a -> a -> a
empty :: Monoid a => a
A monoid is a property of things, not languages, so the idea of "a language without a monoid" doesn't really make sense.Furthermore, if you deploy incorrect code, it could add JSON blobs to the database with the new schema before it crashes on the old schema. Now you've got two incompatible versions of the JSON blob in the DB at the same time, so rolling back to the old code will still be broken!
Software engineers deploying production apps have been dealing with these issues since we started using databases, but that doesn't mean that it's any easier or less error prone. It just means that we have to be more careful. And that care has a cost.
This cost isn't unquestioned for larger systems. It's a big part of the motivation for append-only databases, for example.
http://thesoftwarelife.blogspot.com/2010/12/append-only-data...