You can enter text if you press the square button in the dpad. This will open the whole screen keyboard. I've been using this workaround to load Slashdot and test how the scrolling works. Try it, and file some bugs for the worse offenders in the interface (I've already done that for some text input and title bar problems).
Build a paper prototype of your design and test it with four or five people around you. You can then try several different ideas and find how much people like them or are confused by them.
But by all means, don't interrupt the user actions nor destroy the user data already written in the text field! Those are capital interaction crimes.
A good way to tell the user would be to show the data inconsistency in the input field (by highlighting the text field or the datetime control with a high contrast color change - and beware of color blindness), and reporting the "value is out of range" message in a label inside the dialog, near to the text field.
This design may be a good first approach, but remember to always test interaction designs with real people before putting them into production.
Of course there's a lesson in there: alert dialogs are a idiotic solution to a real problem. Users don't care about them while a task is being performed (they effectively send them to/dev/null), just when the task ends in an undesired way.
So the lesson is: log all those unread dialogs and provide a diagnosis tool where the user can read them all after the task has finished, i.e. when the user will care about what they said. Why is it that computers have log files aimed to developers, but not ones aimed to log in a friendly way the events aimed to end users? Is there really so little empathy in the programmers mindset?
If the user refuses to educate himself to not be a fool, there's really no way to try and make something foolproof.
Then why do you insist in educating them to be fools, by providing them with badly designed dialogs and applications unsuitable for exploratory tasks? (You know, the kind of tasks that would make a good application).
It's not the user's fault that you don't have a clue about the human-computer specifications, but insist to program to that (for you) unknown API.
Except that's definitely not the taskbar at the bottom of the screen AND the taskbar at the top of the screen.
Might that be the reason why the original poster said "It's not quite as flexible as in Ubuntu"? And why on Earth would you want to have the taskbar replicated with exactly the same content at the bottom and the top? Might it be that the poster was referring to having *panels* at the top and the bottom, which would make sense?
Except that's definitely AND. I have right now the taskbar at the bottom of the screen, the quicklaunch bar at the top and a "My PC" toolbar on the right.
Interesting, I didn't see that example as defining a data type. I saw it as selecting a subset of data from a larger set. Yes, that's the typical usage of SELECT. But in this case the GROUP BY creates a classification of the data selected, so that the different subsets created have a meaning. It would have been clearer if I knew how to create groups by age brackets in SQL.:-)
Furthermore, I don't think of declaring or defining data types as computing... in my mind, computing is the act of taking inputs, performing operations, and generating outputs. Data types are merely decorations in order to perform those tasks.
But, again, I may be betraying my own ignorance, here. It certainly seems like Ocaml, Haskell, and other languages, take datatypes to a level with which I am unfamiliar. I think you might have hit an important intuition here. You're on the right track: for programmers with a mathematician mind, programming is the accurate description of data transformations. The changes in state are not that important - if you can describe with precision the relation between input and output, there's no need to know the intermediate operations. Datatypes are a basic building block in that process. The whole SQL language was designed with that intention: you shouldn't need to know how the data is retrieved from the database, just what form and properties will it take after the query ends.
Functional languages often follow the same philosophy (that's why their programs are often called 'declarative'). After you get right the definition of something (say, a type of object in your application), you no longer need to know the details of the definition - you can use that object as an atomic element, a primitive of the language. Imperative languages tried to achieve the same result with encapsulation and structured programming, but the process is not as transparent because the definitions often break due to side effects.
In functional programming you control and limit (or even forbid) the side effects, so you can take care yourself that they never break your encapsulated definitions. So there's no limit to what you can define - you can mix more and more elements to build higher and more complex abstractions.
Does it make any sense to you?
So how 'bout a functional example where people "compute" (ie, take inputs, perform some operations, and generate outputs) in a functional sense?
With this in mind, any example where people think of getting "something new" from "something old", without taking care of the steps by which the new thing is done, would be an example of functional thinking. An example: I pay an accountant to calculate my taxes, and I get all the paperwork solved. Or I press a button on the wall, and my living room is lit. Equations or wiring are not something a normal person would care in those situations - just the desired functions and the requirements to have them executed.
That's also the reason when something breaks (I press the button, but there's no light) people doesn't know what to do: I've fulfilled all the requirements (pressed the switch), why I don't have the result? Since the inner working is not known, that person won't know which of the intermediate operations is failing, so they can't make a correct diagnosis.
in the end, procedural programming is simply more intuitive
Maybe that's the reason why you can do procedural programming in functional languages. And monads are the way to do it; they are so important because they provide the bridge between the imperative and functional worlds, keeping the best of both.
If you really appreciate imperative programming, you should learn how monads work, because monads are a mathematical (declarative) description of procedural computations. Monads are used by building a sequence of operations, much like a Unix pipe, carrying state from one operation to the next. (Why defining a monad then, instead of using an imperative language? Because with the monad, you have the definition visible in your program, instead of hidden in your execution engine/virtual machine).
As for the *why* of monads: they are a Design Pattern in functional languages, just like "Observer" or "Strategy" are design patterns in Object-Oriented Programming. If you structure your code according to the predefined pattern, you'll likely get some benefits in terms of flexibility and mantainability.
The benefits provided by monads are close to those provided by Dependency Injection and Inversion of Control in OOP: you can delegate some complex processing into a supporting framework. Then you can build your application in terms of small blocks whose control flow is handled by the framework in the right order, thus helping reusability and simplifying the bookkeeping a lot.
For the *how* this is done, I recommend reading about the assembly line and space station metaphors (in that order), as well as any explanation intended "for imperative programmers". As I said, the structure of a monad is similar to a Unix pipe, but with user-defined types instead of just plain text. The "lift" and "bind" functions are methods defining an interface to comply with the pattern definition (they are a constructor and a sequencer, respectively).
If you tell a bartender what kind of a drink you want, is that programming? If you tell a robot bartender what kind of a drink you want, is that programming?
If you have to tell the bartender how the drink is made, yes. If the instructions for the drink are already known by the bartender, no.
Ok, so how would a functional algorithm to cooking oven baked salmon look like?
Exactly the same as a procedural algorithm, but wrapped in a do block. **Functional languages can do procedural programming**, that's my whole point. But they are better than imperative languages, because side effects are controled.
When I examine an SQL statement, I specifically think about it in terms of how the data is processed.
That's because you're a programmer. I thought we were talking about "the average everyday human being" here. Or are you talking just about programmers, and all that rhetoric about "how the human mind works" was really about "what programmers in this current generation would do"? Because then you're confirming my position, that your way of thinking is something that programmers learn.
My example was meant to show how non programmers would think of the definition of a data type, and show that they would express it in terms similar to those of a functional declaration. An average person from the street (again, without training in programming) would definitely *NOT* "go through the My_Country table pulling entries that match the select clause". Only a procedural programmer would do that.
no one yet has provided an actual *real world* example of functional/declarative computation in one's everyday life
Your requirements seem contradictory. If you're talking about "one's everyday life", you can't include programming, because in the real world people don't do programming. Clarify what kind of information are you looking for, so that I can tailor an example accordingly.
The average everyday human being don't do programming, bud.
As someone already pointed out before, the normal person also thinks of algorithms in terms of definitions; that's where functional really shines. And as I already pointed out, functional *can* represent algorithms in steps.
The only change in thinking required to understand monads is this one: - in imperative programming, all side effects are predefined in your language's virtual machine. And you'll have unexpected side effects even where you don't want them. - with monads, you can use the predefined side effects, or you can build your own new ones. You'll only have side effects in the places where you activate them, and the only possible side effects will be the ones that you allowed.
Other than that, code inside a monadic do-block is real imperative code. But the state handling is not hidden inside the implementation of your language, it's exposed in your program and libraries.
You can trust me, monads are not really that complex - the problem with them is than nobody teaches them in standard programming (that's because it's a too young discipline, and hasn't entered the mainstream). If you know anything about the inner workings of programming languages, monads are just a special syntax for them. The average programmer is spoiled to understand them with ease because they are rarely taught how a program is executed by the underlying machine; a monad describes how that underlying execution is carried out step by step, and allows you to change it.
Funny that you mention "basic stateful concepts (like I/O)", since your well known I/O *is a monad* at its core. You already know monads! Go figure.
With this "monads-expose-parts-of-the-virtual-machine" mindset, understanding them is not that weird.
If you follow the link I provided above, you'll see it points to something called "do notation". In pure functional glory. Monads made intuitive (at least as much as in your preferred imperative language).
The I/O problem has been solved. Modern functional languages have nothing to envy from procedural ones; and the reverse is not true. Nowadays functional languages manage state changes much better than imperative ones (specially when dealing with concurrency i.e. multiprocessors and networks).
IBEX 35 is the name of the Spanish stock market index. For a moment I thought NASA was issuing shares.
You can enter text if you press the square button in the dpad. This will open the whole screen keyboard. I've been using this workaround to load Slashdot and test how the scrolling works. Try it, and file some bugs for the worse offenders in the interface (I've already done that for some text input and title bar problems).
:)
Why did you have to do this, Felicia? The ABBA turd wasn't enough for you?
</obscure gay geek cinematography joke>
Already going on... and guess who's his opponent.
The name for the second Wii?
Yuu.
Doesn't vim have a case-insensitive replace mode? :-P
s/users/developers/
There, fixed it for you. It hurts, right?
Build a paper prototype of your design and test it with four or five people around you. You can then try several different ideas and find how much people like them or are confused by them.
But by all means, don't interrupt the user actions nor destroy the user data already written in the text field! Those are capital interaction crimes.
A good way to tell the user would be to show the data inconsistency in the input field (by highlighting the text field or the datetime control with a high contrast color change - and beware of color blindness), and reporting the "value is out of range" message in a label inside the dialog, near to the text field.
This design may be a good first approach, but remember to always test interaction designs with real people before putting them into production.
And how about some scientific research?
Of course there's a lesson in there: alert dialogs are a idiotic solution to a real problem. Users don't care about them while a task is being performed (they effectively send them to /dev/null), just when the task ends in an undesired way.
So the lesson is: log all those unread dialogs and provide a diagnosis tool where the user can read them all after the task has finished, i.e. when the user will care about what they said. Why is it that computers have log files aimed to developers, but not ones aimed to log in a friendly way the events aimed to end users? Is there really so little empathy in the programmers mindset?
Then why do you insist in educating them to be fools, by providing them with badly designed dialogs and applications unsuitable for exploratory tasks? (You know, the kind of tasks that would make a good application).
It's not the user's fault that you don't have a clue about the human-computer specifications, but insist to program to that (for you) unknown API.
Where are the mod points when you really need them?
Might that be the reason why the original poster said "It's not quite as flexible as in Ubuntu"? And why on Earth would you want to have the taskbar replicated with exactly the same content at the bottom and the top? Might it be that the poster was referring to having *panels* at the top and the bottom, which would make sense?
Except that's definitely AND. I have right now the taskbar at the bottom of the screen, the quicklaunch bar at the top and a "My PC" toolbar on the right.
Create a "Indie music" wikiproject, and get people to care for those pages. It seemed to work for Webcomics.
No mod points. Launch your lawyers.
Interesting, I didn't see that example as defining a data type. I saw it as selecting a subset of data from a larger set. :-)
Yes, that's the typical usage of SELECT. But in this case the GROUP BY creates a classification of the data selected, so that the different subsets created have a meaning. It would have been clearer if I knew how to create groups by age brackets in SQL.
Furthermore, I don't think of declaring or defining data types as computing... in my mind, computing is the act of taking inputs, performing operations, and generating outputs. Data types are merely decorations in order to perform those tasks.
But, again, I may be betraying my own ignorance, here. It certainly seems like Ocaml, Haskell, and other languages, take datatypes to a level with which I am unfamiliar.
I think you might have hit an important intuition here. You're on the right track: for programmers with a mathematician mind, programming is the accurate description of data transformations. The changes in state are not that important - if you can describe with precision the relation between input and output, there's no need to know the intermediate operations. Datatypes are a basic building block in that process. The whole SQL language was designed with that intention: you shouldn't need to know how the data is retrieved from the database, just what form and properties will it take after the query ends.
Functional languages often follow the same philosophy (that's why their programs are often called 'declarative'). After you get right the definition of something (say, a type of object in your application), you no longer need to know the details of the definition - you can use that object as an atomic element, a primitive of the language. Imperative languages tried to achieve the same result with encapsulation and structured programming, but the process is not as transparent because the definitions often break due to side effects.
In functional programming you control and limit (or even forbid) the side effects, so you can take care yourself that they never break your encapsulated definitions. So there's no limit to what you can define - you can mix more and more elements to build higher and more complex abstractions.
Does it make any sense to you?
So how 'bout a functional example where people "compute" (ie, take inputs, perform some operations, and generate outputs) in a functional sense?
With this in mind, any example where people think of getting "something new" from "something old", without taking care of the steps by which the new thing is done, would be an example of functional thinking. An example: I pay an accountant to calculate my taxes, and I get all the paperwork solved. Or I press a button on the wall, and my living room is lit. Equations or wiring are not something a normal person would care in those situations - just the desired functions and the requirements to have them executed.
That's also the reason when something breaks (I press the button, but there's no light) people doesn't know what to do: I've fulfilled all the requirements (pressed the switch), why I don't have the result? Since the inner working is not known, that person won't know which of the intermediate operations is failing, so they can't make a correct diagnosis.
Maybe that's the reason why you can do procedural programming in functional languages. And monads are the way to do it; they are so important because they provide the bridge between the imperative and functional worlds, keeping the best of both.
If you really appreciate imperative programming, you should learn how monads work, because monads are a mathematical (declarative) description of procedural computations. Monads are used by building a sequence of operations, much like a Unix pipe, carrying state from one operation to the next. (Why defining a monad then, instead of using an imperative language? Because with the monad, you have the definition visible in your program, instead of hidden in your execution engine/virtual machine).
As for the *why* of monads: they are a Design Pattern in functional languages, just like "Observer" or "Strategy" are design patterns in Object-Oriented Programming. If you structure your code according to the predefined pattern, you'll likely get some benefits in terms of flexibility and mantainability.
The benefits provided by monads are close to those provided by Dependency Injection and Inversion of Control in OOP: you can delegate some complex processing into a supporting framework. Then you can build your application in terms of small blocks whose control flow is handled by the framework in the right order, thus helping reusability and simplifying the bookkeeping a lot.
For the *how* this is done, I recommend reading about the assembly line and space station metaphors (in that order), as well as any explanation intended "for imperative programmers". As I said, the structure of a monad is similar to a Unix pipe, but with user-defined types instead of just plain text. The "lift" and "bind" functions are methods defining an interface to comply with the pattern definition (they are a constructor and a sequencer, respectively).
If you have to tell the bartender how the drink is made, yes. If the instructions for the drink are already known by the bartender, no.
Exactly the same as a procedural algorithm, but wrapped in a do block. **Functional languages can do procedural programming**, that's my whole point. But they are better than imperative languages, because side effects are controled.
That's because you're a programmer. I thought we were talking about "the average everyday human being" here. Or are you talking just about programmers, and all that rhetoric about "how the human mind works" was really about "what programmers in this current generation would do"? Because then you're confirming my position, that your way of thinking is something that programmers learn.
My example was meant to show how non programmers would think of the definition of a data type, and show that they would express it in terms similar to those of a functional declaration. An average person from the street (again, without training in programming) would definitely *NOT* "go through the My_Country table pulling entries that match the select clause". Only a procedural programmer would do that.
Your requirements seem contradictory. If you're talking about "one's everyday life", you can't include programming, because in the real world people don't do programming. Clarify what kind of information are you looking for, so that I can tailor an example accordingly.
As for an "instance of a normal, everyday situation in which humans use a functional model of computation":
SELECT Name, Age FROM My_country
WHERE Age > 18
GROUP BY Age
You'd be hard pressed to find someone thinking of the age groups in their country using a "for..next" model.
The average everyday human being don't do programming, bud.
As someone already pointed out before, the normal person also thinks of algorithms in terms of definitions; that's where functional really shines. And as I already pointed out, functional *can* represent algorithms in steps.
The only change in thinking required to understand monads is this one:
- in imperative programming, all side effects are predefined in your language's virtual machine. And you'll have unexpected side effects even where you don't want them.
- with monads, you can use the predefined side effects, or you can build your own new ones. You'll only have side effects in the places where you activate them, and the only possible side effects will be the ones that you allowed.
Other than that, code inside a monadic do-block is real imperative code. But the state handling is not hidden inside the implementation of your language, it's exposed in your program and libraries.
You can trust me, monads are not really that complex - the problem with them is than nobody teaches them in standard programming (that's because it's a too young discipline, and hasn't entered the mainstream). If you know anything about the inner workings of programming languages, monads are just a special syntax for them. The average programmer is spoiled to understand them with ease because they are rarely taught how a program is executed by the underlying machine; a monad describes how that underlying execution is carried out step by step, and allows you to change it.
Funny that you mention "basic stateful concepts (like I/O)", since your well known I/O *is a monad* at its core. You already know monads! Go figure.
With this "monads-expose-parts-of-the-virtual-machine" mindset, understanding them is not that weird.
If you follow the link I provided above, you'll see it points to something called "do notation". In pure functional glory. Monads made intuitive (at least as much as in your preferred imperative language).
Impressed yet?
The I/O problem has been solved. Modern functional languages have nothing to envy from procedural ones; and the reverse is not true. Nowadays functional languages manage state changes much better than imperative ones (specially when dealing with concurrency i.e. multiprocessors and networks).