2 ms·
How do I express my models of programs on paper that doesn't easily translate into math? I understand that the part of programs there you have a formula on befo
by dr0wsy 7y ago
How do I express my models of programs on paper that doesn't easily translate into math? I understand that the part of programs there you have a formula on beforehand (e.g., convert between Celsius and Fahrenheit) is easily expressed in a mathematical formula before implementing it. However, how should I express I/O?
Often when I have a problem that isn't easily expressed in mathematical notation (albeit to my limited knowledge of math), I usually got a good idea of how I could express it in code.
When I write pseudo code it often feels like I already have the code in my mind before I describe in plain English. That feels like a waste of time. So pseudo code doesn't feel like a great tool to express models of my programs.
- wa1987 7y ago> However, how should I express I/O? First thing that comes to mind is category theory, especially monads. Haskell's I/O monad for example: https://en.wikipedia.org/wiki/Monad_(functional_programming)#IO_monad_(Haskell) https://en.wikipedia.org/wiki/Monad_(functional_programming)...
- codr7 7y agoBut why? Having to sweet talk the compiler into simply reading/writing data by building towers of super abstract mathematical concepts doesn't look like a win from here. If that's the cure, I'll take the disease.
- wa1987 7y agoThe question was about expressing I/O as a mathematical concept (on paper), not about talking to compilers.
- codr7 7y agoHaskell and others have pretty much proved it's possible in practice as well. But from my experience the cure is worse than the disease. Wishing that software was as formal as math is one thing. Pretending it is leads nowhere worth going. I have most of my feet in the C++/Common Lisp camps these days. Where you accept that the world is a messy place with complex problems that don't fit neatly into labeled boxes, and use the most powerful tools you can think of to deal with it.
- jcora 7y agoMath isn't formulas. The part of math that is most useful for programming are algebraic structures. Many "patterns", conventions, frameworks, etc., are just bastardizations of mathematical patterns. What really matters is the composition of concepts, and what better way to think about that than mathematically? So if you want your programming to reap the benefits of (others', mostly) mathematical reasoning--use a functional language that is all about expressing the ways in which things compose! IO is modelled pretty well through monads. As are many other things, like nondeterministic processes, exceptions, state, etc.
- dr0wsy 7y ago> So if you want your programming to reap the benefits of (others', mostly) mathematical reasoning--use a functional language that is all about expressing the ways in which things compose! I do prefer using functional language over imperative ones, but I don't understand that is connected to model software on paper? > IO is modelled pretty well through monads. As are many other things, like nondeterministic processes, exceptions, state, etc. Isn't there any easier way to describe I/O than with category theory? I understand that it's _possible_ to model IO with monads, but how would I communicate it with colleagues that doesn't have a background in category theory (or myself for that matter)? Part of the benefits with modelling a program on paper should be to make communication easier. And to require people you communicate with to have knowledge in category theory to understand your design fells silly. I probably misinterpret you, so could you please give a more detailed explanation or example?
- jcora 7y ago> but I don't understand that is connected to model software on paper I was talking more generally about techniques that allow for sneaking in mathematical thinking in various stages of development, not just modelling. Largely because of the very precise types which make a large part of your program verifiable (and force you to think about a lot of things you wouldn't have if you were using, say, JavaScript). I was recently making a script engine for a game. It was really neat to realize that the "runScript" method was literally just a mapping between two monads. No special state inbetween, no complex logic, no file lookup or anything like that. These types of insight accumulate, and there's really a tonne of stuff to learn (this potential for learning the language itself feels much greater in functional programming for me). > Isn't there any easier way to describe I/O than with category theory? This isn't category theory! Do you really think every working Haskell programmer is some mathematician? No. Look at this random image I googled, you think Haskell programmers understand this? https://i.stack.imgur.com/4IzGk.png https://i.stack.imgur.com/4IzGk.png Most mathematicians don't! The notion of a monad in functional programming might be inspired by category theory, but you're really better of not taking that connection too seriously. Functors, applicatives, and monads are all very simple notions that should be understood as programming constructs, not arcane math. If you want an area of math to research to most benefit your functional programming, that is undoubtedly mathematical logic and/or intro-level type theory, and not category theory. (This should take you in the direction of dependent types.) Really, types are the key. The notion of a monad is best understood not through vague real-world analogies with sandwiches, but through the type and implementation of its >>= method. The reason for that is that the point of monads is in composition. And basic linear algebra is enough to understand the importance of composition, not category theory. Just look at the Maybe monad to immediately understand it: Nothing >>= f = Nothing, Just x >>= f = f x, where f : a -> Maybe b. Isn't this a really clear, intuitive way of composing operations which might fail? Same goes for IO. The only thing you're doing is composing some values. When you compose an IO Int with some function of the type Int -> IO (), you get back a value of type IO () (which your runtime executes if you bind it to main). All of this is right in the type, and it's just as intuitive a way of composing IO values as Maybe ones, IMO. You get the added benefit of execution becoming not a side-effect, but a first-class member. Evaluation of IO programs is not their execution, you could evaluate putStrLn "asdf" a million times without it being executed. You can literally store those programs (values) somewhere and execute them later.
- justinmeiners 7y agoAuthor here. I would say that modeling the computational process in math is not typically helpful (you already have a formal programming language) you should model the real-world (or at least computer world) problem you are trying to solve. Carefully define operations and constraints, introduce abstractions for solving them, etc. Do you have an example of an I/O problem you have thought about that you would like me to talk more about?
- dr0wsy 7y agoThanks for the article and discussion that sprang up around it! The question I'm trying to ask is how I should express (part of) programs on paper using math when I don't see how they are related to math. Example: How could I easily express a function that takes a string as input and outputs the string capitalized using math notation? I understand that the problem you solve in the post should probably be put on paper first before you began writing any code. My problem is to express programs in math when "calculate" isn't part of the problem description, like it is in the example in the blog post. Edit: Changed example question.
- justinmeiners 7y agoThis is a great question. What I really tried to emphasize in the article is that math is not a formal language. Since its just you and coworkers, write out the parts you need as you need them, and ignore details. After all, its an exercise to help you think. If I needed uppercase I would just say: `up(s)` is a function that maps a string s to its uppercase string Writing that down, you and I already have a pretty good idea of how it works, or its included in our libraries, and we can figure out the details when writing the code. This is of course assuming `uppercase` is a minor part of another algorithm. If it was the subject of discussion I might describe it like this: Let `u(c)` be a function that maps a characters to its uppercase character. In ASCII `u(c) = c + K` where K is some offset. To capitalize an entire string we need to apply that function to each character. Let `up(s)` = (u(c_1), u(c_2), ... u(c_n)) where the string s = (c_1, c_2, ... c_n) Perhaps that helps, but I don't think it addresses your question directly. I think you need some experience reading math to know how to describe problems, but I don't think you need to know fancy math. A knowledge of functions, sets, tuples, logic, summations, etc, will get most of what you need. I highly recommend that book I linked in the article: "Introduction to Graph Theory" By: Trudeau