Hacker Newsnew | past | comments | ask | show | jobs | submit | jekor's commentslogin

Which email address?


nick@uploadvr.com


Global DevOps Lead - Zalora - http://worldwide.zalora.com/ - Singapore - VISA, REMOTE

We need someone with experience running large websites. We already have 5 very talented developers with systems and networking experience who are already managing the sites on a day-to-day basis. They need someone to lead them: guide designs, anticipate problems, communicate with other departments, prioritize projects, etc. You will need to have a strong development background even though this is not a developer position.

If you can do the job, you can work from anywhere or we will get you a visa to work from our offices in Singapore (assuming you don't live here already). Singapore is an ideal location for living in and exploring South East Asia.

Tech used: Nix/NixOS, Linux, Haskell, VirtualBox, Puppet (for legacy servers)

Apply (and read more details) at http://jobs.engineering.zalora.com/apply/DHuzeh/Global-DevOp...


REMOTE - Global DevOps - Haskell and Nix

We're looking for 1 more developer with systems/operations experience to join us. We are a team of 5 working to simplify and automate operations of our 7+ networks of websites and internal services across Southeast Asia. The entire team is remote.

We've built and tested a Nix(OS)-based network powering a traditional LAMP stack, running on AWS. Initially deployed with NixOps, we've since started deploying it with our in-house tool written in Haskell (https://github.com/zalora/upcast). Currently in testing, it will soon be in production serving 7+ countries and 1 million+ customers.

We release as much as we can under Free Software licenses and contribute upstream to open source projects when possible. We have no fixed schedules and no deadlines. Your job would be to learn your way around our infrastructure (and enhance our growing wiki in the process), take pager duty 1 out of every 6 weeks, and find yourself projects that will challenge and motivate you to create value for the company.

Apply here: http://jobs.zalora.com/apply/lOd9Ir/Global-DevOps-Engineer-R...


Zalora - http://jobs.zalora.com/ - Singapore/REMOTE (full-time, Haskell, NixOS)

We're hiring functional programmers for development and DevOps positions. Our tools of choice are Haskell and NixOS, and we apply purely functional principles anywhere we can.

You'll be working with an experienced team, but you'll still have the opportunity to influence the design of our systems. We sell fashion products online in Southeast Asia, and the work involves building out a new NixOps-managed network, writing daemons/tools for a service-oriented architecture (primarily web-based), and the odd data science/machine learning problem (if that interests you).

We can assist you with relocation to Singapore, or you can work remotely and travel there occasionally. Apply via our jobs board at http://jobs.zalora.com/


SEEKING WORK - Remote

Web Developer/DevOps

Haskell, PHP, JavaScript, Python, Linux, PostgreSQL, MySQL

Several years of experience working remotely for high traffic sites (> 1 billion page views per month) and a deep understanding of big data/large infrastructure. I've worked on everything from large JavaScript codebases, optimizing and normalizing databases, to writing high-performance PHP extensions in C.

I take pride in what I write and document it for future maintainers. My email address is available on my site and I'd be happy to talk with you about your needs.

http://jekor.com/


Yes, a lot of these are characteristic of functional programming, and many are being adopted. But I think that the idea of using mathematically pure functions---programming without side effects or mutation---is a/the key idea behind functional programming. And it's this purity that divides the communities. You can take high-order functions and folds and put them in just about any language, and you could put OOP concepts like subtype polymorphism into functional languages. But there's a line that neither class of languages can cross over, and that's mutable state.

I know that some developers are beginning to lean in the direction of functional programming by relying on const annotations and adopting a functional style. And I'm very excited and hopeful about the overall trend.


But I think that the idea of using mathematically pure functions---programming without side effects or mutation---is a/the key idea behind functional programming.

Indeed, and it is either a blessing or a curse depending on what kind of software you’re trying to write and the sort of situations you’re trying to model.

For most of the programming work I’ve ever done myself, what I’d really like to use is languages that do have concepts like time and side effects, because they’re very useful, but which only use them in controlled ways and when the programmer actually wants them. I’ve often wondered whether such ideas might be elevated to first class concepts within future programming languages, complete with their own rules and specified interactions, just as today we have variables and types and functions, and a language will prevent errors like calling a function with only two values when it expects three or trying to use the value 20 where a string is expected.

For now, I’m hoping that functional programming, in the pure sense, will raise awareness of the potential benefits of controlling side effects rather than allowing them more-or-less arbitrarily as most imperative languages today do. With a bit of luck, the generation of industrial languages in a few years will then borrow ideas that stand the test of time from today’s research into type/effect systems, software transactional memory, and so on, and perhaps we can have something of the best of both worlds.


What you describe is exactly what Haskell does. You have pure functions by default, but you can have mutable state wherever you want it--it is just constrained to a particular scope by the type system. That is, you can use mutable references, mutable arrays and so on all you want inside a computation, and the compiler will guarantee that none of these references leak outside their scope. Haskell accomplishes this with "state threads" (ST[1]).

[1]: http://hackage.haskell.org/packages/archive/base/4.2.0.1/doc...

Similarly, Haskell has the IO type for containing any side effects at all. This type, as the name implies, can have not only mutable state but also arbitrary I/O--really anything you like.

This has some very nice advantages: for example, you can create your own wrapper around the IO type which only exposes some IO operations. You could use this for ensuring that plugins can't do things like delete files, for example. (This is one of the example use cases for Safe Haskell[2], which is worth reading about.)

[2]: http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/safe-...

You can even reify time explicitly, rather than modelling it implicitly with mutable state. This leads to functional reactive programming (FRP[3]), a new and more declarative way to write things like UIs. FRP replaces event and callback oriented programming, fixing much of the spaghetti code common to most UI frameworks.

[3]: http://stackoverflow.com/questions/1028250/what-is-functiona...

Really, I think "purely functional" is a very unfortunate term for Haskell from a marketing standpoint. "Purely functional" does not mean that we cannot have side-effects, or mutation, or what have you. It just means that side-effects aren't everywhere by default, and don't implicitly permute your otherwise pretty code.


I appreciate the comment, but what I have in mind looks very different to the way monads are used in Haskell today.

For example, I don’t necessarily want pure functions by default in my idealised programming model. To me, a pure function is just a special case of a function whose effects are controlled and where the resources the function might interact with are readily identifiable, for which the sets of possible effects and interacting resources happen to be empty.

Put another way, I don’t see anything wrong, or even inferior or undesirable, with performing a quicksort of an array or some fast matrix computations destructively. However, I’d like my language to make sure I couldn’t accidentally try to use the old data again afterwards (including, for example, in other threads running in parallel). I’d like to be sure that just because my algorithm updates one set of data in-place, it doesn’t also draw a window, block to wait for user input, or kick off a background thread that will reformat my hard drive in half an hour. And in the calling code, I’d like to find out very quickly that just because I created and populated an array over here, and then ran a quicksort that changed it over there, and then printed it out down there, nothing else had any chance to modify it in between.

And I’d like to do all of that using syntax that is at least as clean and readable as today’s best languages, please, not the horrors that often seem to result when functional programming languages try to implement equivalent behaviour with realistic heavily structured/monadic values instead of the neat one-integer counter or append-only log that always seems to be used in the tutorial code samples.

I suspect that to do that will require a language that provides dedicated, specialised tools to support the new programming model. Sure, you could probably do this sort of thing using monads in Haskell, just as you could do OOP in C, text processing in C++, or write in a functional style in Python, but the results are clumsy compared to using the right tool for the job. I’m not sure that tool exists yet for the kind of programming models I’d like to use, but that’s where I’m hoping the lessons of today’s functional languages and academic research will bear fruit over time.


That's very attainable in Haskell and is often well-modeled off the ST monad. You also have a number of "Data types a la carte"-like methods which allows you to build very specific effect contexts in order to precisely guarantee things like the fact that mutable array code never produces events in the UI. These can be achieved by products and compositions of applicative types, free monads, monad transformers, or the "sum of effects" "a la carte" method.

Another big deal that comes out of these more specific effects is that you can have the compiler produce stream fusion to automatically optimize some inner loops, though I don't know how often that actually happens as of today.

(Oh: if you want to play with "Data types a la carte" they're in the IOSpec package, http://hackage.haskell.org/package/IOSpec and are described---somewhat densely---in http://www.staff.science.uu.nl/~swier004/Publications/DataTy...)


You should really take a look at Haskell. What you describe in your 3rd paragraph is precisely the ST monad.

It's true we're still pretty limited in how effects are typed (most effectful stuff still ends up in the "IO sin-bin"), but this is an area of active research and experimentation. This is the way haskell's going, and no one else is even close (afaict).


What you describe in your 3rd paragraph is precisely the ST monad.

Not exactly. The ST monad supports local mutable state, essentially turning a computation that uses state internally into something that looks pure from the outside. I’m looking for something more general where, for example, a function could modify state outside its own scope, but only if it advertised explicitly which stateful resources it would read and/or write, so the language could enforce constraints or issue warnings if various kinds of undesirable and/or non-deterministic behaviour would result.

And really, I want to generalise the concepts of resources and effects on them much more widely. A stateful resource might be a mutable variable, but it could just as well be a file, a database, a single record within a whole database, or anything else I care to model in that way. An effect might be reading or writing part of the state, but it might also be opening or closing a file, or beginning, committing or rolling back a DB transaction. I want a language that can understand the concept that a file must not be read or written before it is opened, or that a database transaction must always be committed or rolled back once it has begun, and warn me if any code paths could permit an invalid order of effects. I don’t just want to throw half my code into the IO monad and hope for the best.

I want a language where I can pass a reference to a large data structure into a parallel map function and get a compile-time error because, somewhere in the function I was applying using the map, there was an attempt to perform a mutating operation on that shared data without sufficient safeguards. But I want to write almost identical code and have the effects automatically co-ordinated because the language understands that concurrent access is possible so synchronisation is necessary, but the spec for the parallel map says that non-determinism is permitted.

And crucially, I want a language where even simple code that should look like this:

    def fib(n):
        if n < 2:
            return n
        x, y = 0, 1
        for i in range(n - 1):
            x, y = y, x + y
        return y
does not wind up looking like this (from [1]):

    fibST :: Integer -> Integer
    fibST n = 
        if n < 2
        then n
        else runST $ do
            x <- newSTRef 0
            y <- newSTRef 1
            fibST' n x y
     
        where fibST' 0 x _ = readSTRef x
              fibST' n x y = do
                  x' <- readSTRef x
                  y' <- readSTRef y
                  writeSTRef x y'
                  writeSTRef y $! x'+y'
                  fibST' (n-1) x y
[1] http://www.haskell.org/haskellwiki/Monad/ST


Your last complaint is not fundamental to the language: it's just a matter of library design. I guess Haskellers don't like state very much in any guise, so having awkward syntax for it is only natural. Both programs are fundamentally ugly, so having it be superficially ugly as well is no big loss.

However, if you really wanted to, you could have almost C-like syntax[1]. The demo in that particular blog post has its own issues, but there is no fundamental reason why you couldn't apply some of those ideas to the normal ST API. I suspect that people simply don't care enough.

[1]: http://augustss.blogspot.co.il/2007/08/programming-in-c-ummm...


Both programs are fundamentally ugly, so having it be superficially ugly as well is no big loss.

Perhaps we’ll just have to amicably disagree on that point. I think making code superficially ugly is a huge barrier to adoption that has held back otherwise good ideas throughout the history of programming.

Many an innovative programming style or technique has languished in obscurity until some new language came along and made the idea special and provided dedicated tools to support it. Then it becomes accessible enough for new programmers to experiment with the idea, and the code becomes readable enough to use the idea in production, and over time it starts to change how we think about programming. We push the envelope, probably developing some ingenious and useful but horrible abuses of the idea along the way, until we figure out how to make those new ideas available in a cleaner and more widely accessible way and the cycle begins again.

I suspect that people simply don't care enough.

Most people are programming in languages that don’t have the problem in the first place, so they don’t need to care.


> I think making code superficially ugly is a huge barrier to adoption that has held back otherwise good ideas throughout the history of programming.

Haskell tries to make elegant code look nice and inelegant code look ugly. When you see something ugly like the example above this is a sign that there would be some more elegant way of writing it. That certainly holds in this case as you don't need an mutation to do the fib sequence.


For something as simple as fibonacci, you wouldn't use the state monad machinery, but go directly:

    fib' :: Integer -> Integer
    fib' n = iterate (\(x,y) -> (y,x+y)) (0,1) !! n
The state monad helps you keep more complicated code composable. But it does have some syntactic overhead, that makes it lose out in simple examples. (Though with a bit of golfing, you could get syntactically closer to the Python example. For example putting the tuple (x,y) into an STRef instead of having two of them, employing Applicative Functor style in some places, and using a loop-combinator from the monad-loops package.)


Concepts like your file state machine can be achieved using indexed monads and dependent types, though that's still fairly black magic. There's no doubt that the IO monad should have more structure, though, and ST is just one way to achieve that. There isn't a globally recognized standard for providing more structure, but there are a lot of fairly common practices (see IOSpec or free monads).

The syntactic convenience is unbeatable, of course. Monads are only first class syntactic notions up to `do` notation. Someone is bound to say "let just implement that in Template Haskell", but nobody really argues that TH macros are the same as lispy ones.


The syntactic convenience is unbeatable, of course.

Exactly.

I’m not in any way criticising all the research and ideas coming out of the functional programming community. Playing with Haskell is driving all sorts of interesting ideas.

I’m just saying I don’t think the mainstream is going to give up a whole bunch of readily accessible and useful programming techniques any time soon, just to gain the benefits of a radically different programming style that sound rather theoretical to Bob the Developer. This is true even if the reality might be that in time Bob’s bug rate would drop dramatically and he would develop new features in a fraction of the time.

I think it’s far more likely that the more accessible and obviously useful parts of that radically different programming style will get picked up over time, and that the underlying general/theoretical foundations will be more useful to the people building the specific/practical tools than to the people using them.

Today, we’ve been discussing how to implement even quite simple effect-related concepts in a functional programming context in terms of (borrowing from a few of your posts in this thread) products and compositions of applicative types, free monads, monad transformers, indexed monads, dependent types, and the problems of uncertain denotation. Poor Bob just wants to get an error message if he forgets to commit his transaction and leaves the DB locked or if he might be dereferencing a null pointer in his network stack. :-)


That's utterly fair. I don't expect Bob the programmer to adopt inconvenient things. I think having static assurances of the like you were asking for will probably never quite be in Bob's purview either, though.

To clarify, I don't think Haskell is the ultimately useful embedding of many of these concepts. I just also don't think there's that much hand holding possible. You start to run up against the limits of inference and decidability in this space. Until Bob the programmer start to meaningfully think about the way to build the effects of his language around different contexts then there's a limit to how many guarantees a compiler is going to be able to make.


What you describe reminds me of Rust's typestate, which they removed. But the "branded types" replacement, combined with the unique pointers, sound promising - see http://pcwalton.github.com/blog/2012/12/26/typestate-is-dead...

I am new to Haskell, but I also have objections to Haskell's notions of purity. For example, accessing your pid or your argv do not have side effects, and certainly do not perform IO, yet these are grouped in the IO monad next to file deletion.


Runtime constant values as IO is a long-standing concern. The existence of withArgs cements the issue (definitely allows for non referentially transparent code to be written with getArgs) but there's more to be said about why withArgs exist and why getArgs is in the IO monad.

http://www.haskell.org/pipermail/haskell/2005-October/016574...

The argument usually seems to play out as "their denotation is uncertain" and therefore they get unceremoniously thrown into the IO monad. I tend to agree with that in that I feel a major point of purity is that it gives you a world sufficiently far from the reality of the RTS to play in.

IO's general status as the "Unsafe Pandora's Box" is a wart in Haskell. I'd much prefer it be called the RTS monad and have something like IOSpec's Teletype type performing the classic IO. It's fixed by convention now though.


IO's general status as the "Unsafe Pandora's Box" is a wart in Haskell.

Isn’t that rather like saying mutable variables are a wart in C? :-)


It's more like saying void pointers are a wart in C. It's appropriate in two ways: for one, void pointers are a wart, and for two, there's no good way to get rid of them without radically changing the language.


Sure. Haskell's wart is automatically verified to be context constrained by the type system, though. There are also lots of tools to mitigate that wart that are also verified.


I agree. Tight, stateful algorithms aren't going to disappear and are harder to reason about (currently) in functional languages. I expect that their implementation and use will shrink over time, in the same way that embedding inline assembler has all but disappeared.

I definitely don't expect, or hope, that monads are the final answer to isolating state manipulations, and I agree with a later comment of yours that the IO monad is not granular enough as it is in Haskell. When a large chunk of code ends up being written in the IO monad or in another monad that wraps IO, you miss out on a lot of safety and reasonability that Haskell is supposed to give you. And I've seen that happen (my own projects included).


"But there's a line that neither class of languages can cross over, and that's mutable state."

I'd add another qualifier for clarity; default or reliable mutable/immutable state. And this really comes up in libraries and such; either the language affords the use of immutability and you can count on libraries being themselves immutable, or the language affords the use of mutation and you can count on the libraries being based on mutation. Immutable languages can "borrow" mutability and mutable languages can "borrow" immutability (const, etc.), but the default matters, and there has to be some sort of default.

(Though while I cast this as a binary, there are some small in-between choices that may be relevant; see Rust, for instance, whose "unique" pointers may be a successful split. If the most useful aspect of immutability is not strictly speaking the inability to mutate values, but instead to guarantee that values can not be mutated by other threads or functions you didn't expect, then what happens if you directly express only that constraint instead of the stronger and more annoying constraint of full immutability? I'm watching that language with interest.)


REMOTE DevOps - deviantART, Inc. (http://deviantart.theresumator.com/apply/tevH3P/DevOps-Engin...)

We're an Alexa top-150 site with a very small and tight DevOps team. For leverage, we automate as much as possible and build tools when they don't already exist.

You'll be working directly with a few other senior DevOps engineers. You will not have to report to any non-engineer managers.

Did I mention that the position is remote?


Would you mind answering a couple of extra questions about the opening? My email address is in my profile if you'd prefer not to post yours here. Thanks!


REMOTE

deviantART (http://deviantart.theresumator.com/apply/tevH3P/DevOps-Engin...)

We're serious about the "Dev" part of DevOps. Don't apply unless you can show us some of your code. We're constantly building new tools and improving the way we administer our architecture.

We're a small, closely-knit, geographically distributed team, and we're looking for one more member.


Ah yes, good point. Luckily we have a regular rate of messages and we knew that 2 million would be enough to always have roughly 24 hours worth.


We're hiring nothing but remote developers from around the globe here at deviantART. We also have flexible schedules. I'm probably biased, but I think we have some of the best web developers in the world because of this.

Our existing development team is already distributed, so all of our systems and workflow are already setup to handle remote development and different timezones. We have a lot of technical challenges to solve and interesting projects, so if you think you have what it takes: http://deviantart.theresumator.com/apply/eR4wR2/


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: