Exercising a choice from another choice; self-reference - daml

I keep on wanting to exercise a choice from another choice (for the same template). Is there a way to do this without knowing the contract id? i.e. I can't call exercise ??? MyChoice from the body of another choice, without knowing ???. Or am I trying to do something fundamentally wrong? Ideally something like exercise this.id MyChoice

There is an implicit variable self which is the contract ID of this given to every choice. So for example,
nonconsuming choice NoConsume : Int
controller p
do return 41
postconsuming choice PostConsume : Int
controller p
do (+2) <$> exercise self NoConsume -- Yes, fetching self in a postconsuming choice is ok.

From an internal DA conversation:
moritz.kiefer 9 days ago exercise self MyChoice works iirc?
andrae.muys 9 days ago self was introduced for precisely this
purpose. Be aware that the contract will be archived before your
choice exercises in consuming choices. You need to use a
post-consuming or non-consuming choice to avoid this.
Luciano 9 days
ago Is postconsuming documented? I don't recall seeing it.
moritz.kiefer 9 days ago
https://docs.daml.com/concepts/glossary.html#postconsuming-choice
there is also a blogpost somewhere iirc
moritz.kiefer 9 days ago
Found it https://blog.daml.com/daml-driven/daml-choice-annotations
blog.daml.comblog.daml.com DAML choice annotations This post reviews
the consuming concept and explains the meaning of the newly added
preconsuming and postconsuming keywords.

Related

How to convert string to json and vice versa in flutter?

Hi below is the json that I need to extract data from.
[
"http://activepeersai.computing.dcu.ie/feedback_participant/114",
"http://activepeersai.computing.dcu.ie/peerLearningPrompter/4",
"{\"0\":{\"feedback_id\":114,\"timer_used\":1,\"timer\":10.0,\"question1\":\"How to break ice with strangers (in social gathering & in formal events) ?\",\"question2\":\"How to build networking (with those from different age, culture, education background, language\\u2026)(in university & in workplace) ?\",\"question3\":\"\",\"question4\":\"\",\"question5\":\"\",\"question6\":\"\",\"question7\":\"\",\"question8\":\"\",\"question9\":\"\",\"question10\":\"\"},\"1\":{\"feedback_id\":115,\"timer_used\":1,\"timer\":10.0,\"question1\":\"How to deal with difficult teammates (dominating \\/ debater character \\/ negative \\/ lack of confidence \\/ free rider\\u2026) ?\",\"question2\":\"How to build mutual trust with teammates ?\",\"question3\":\"\",\"question4\":\"\",\"question5\":\"\",\"question6\":\"\",\"question7\":\"\",\"question8\":\"\",\"question9\":\"\",\"question10\":\"\"}}",
"{\"id\":{\"0\":1,\"1\":2,\"2\":3,\"3\":4,\"4\":5,\"5\":6,\"6\":7,\"7\":8,\"8\":9,\"9\":10,\"10\":11,\"11\":12,\"12\":13,\"13\":14,\"14\":15,\"15\":16,\"16\":17,\"17\":18,\"18\":19,\"19\":20,\"20\":21,\"21\":22,\"22\":23,\"23\":24,\"24\":25,\"25\":26,\"26\":27,\"27\":28,\"28\":29,\"29\":30,\"30\":31,\"31\":32,\"32\":33,\"33\":34,\"34\":35,\"35\":40,\"36\":41,\"37\":42,\"38\":43,\"39\":44,\"40\":45,\"41\":46,\"42\":47,\"43\":48,\"44\":49,\"45\":50,\"46\":51,\"47\":52,\"48\":53,\"49\":54,\"50\":55,\"51\":56,\"52\":57,\"53\":58,\"54\":59,\"55\":60,\"56\":61,\"57\":62,\"58\":63,\"59\":36,\"60\":37,\"61\":38,\"62\":39},\"name\":{\"0\":\"Why did the sharer choose this skill as the most confident skill and why did the learner wants to improve this skill?\",\"1\":\"Can you share another situation whereby using this skill made a very big difference to the outcome? What did you do? What was the result? What might have happened if this skill wasn't brought to the situation?\",\"2\":\"What advice do you have to give to others about becoming better at using this skill in their work and in their lives generally?\",\"3\":\"What can hold people back from being better at this skill? How can you encourage them to overcome these challenges?\",\"4\":\"What would be the outcome if this session\\/series was a huge success? How would we know if this happened?\",\"5\":\"What is working for you now? What is stopping you from moving forward?\",\"6\":\"What do your role models do that you would love to learn\\/incorporate as habits\\/adopt as a mindset?\",\"7\":\"\\\"What got you here won't get you there.\\\" What is your reaction to that statement? What actions have got you to this point that may not serve you if you move forward? What new behaviours do you need to adopt?\",\"8\":\"What would be the outcome if this session\\/series was a huge success? How would we know if this happened?\",\"9\":\"If you had all the time, people, money, resources that you might possibly need, what would you do differently? Does that energise you, frighten you or a bit of both?\",\"10\":\"What do you think you need to do get a better result (or closer to your goal)?\",\"11\":\"What is the worst that could happen and how could you handle it? What is the best that could happen and how could you handle it?\",\"12\":\"What have been the most impactful decisions that you've made in your career? What led to making those decisions? Were you aware of the impact those decisions would have? What would you say to others in a similar position?\",\"13\":\"What habits have stood you in good stead? Are there things that you do regularly, daily or very often that have made a big different over time?\",\"14\":\"Can you share an experience that was transformational for you, taught you a long-lasting lesson or was particularly memorable for its benefits and challenges?\",\"15\":\"How do you think experience affects somebody's perspective, way of making decisions or their feelings about taking risks?\",\"16\":\"Can you describe your target market for your business or who might your ideal employer be?\",\"17\":\"Can you share details of a project that you worked on recently? Why were you or your business chosen to work with this client\\/employer? What were the success and challenges along the way?\",\"18\":\"What makes you\\/your product\\/your service different to others? Why would a client or employer choose what you do over others?\",\"19\":\"What might I be able to do to help you?\",\"20\":\"What is the key problem that you are facing currently?\",\"21\":\"If that problem was solved, what impact would it have?\",\"22\":\"In order to get to that outcome, what do we need to do, what resources need to be invested and any other changes to be made?\",\"23\":\"Is there a willingness to take that action to get towards that outcome?\",\"24\":\"What assumptions are being made? How likely are each one to happen? What would be the impact of those assumptions happening or not happening?\",\"25\":\"What application of the SCAMPER technique could be useful to help get another perspective?\\n*SCAMPER is an acronym formed from the abbreviation of: Substitute, Combine, Adapt, Modify (Also magnify and minify), Put to another use, Eliminate and Reverse.\",\"26\":\"If we had double the budget, half the time and were living in another country trying to make this happen, how might we think differently?\",\"27\":\"If any idea generated already in this discussion was to become a reality, what would be the impact on e year later in terms of benefits, ongoing coasts, sustained behavioural change and a launchpad for further growth?\",\"28\":\"Leadership\",\"29\":\"Communication\",\"30\":\"Adaptability\",\"31\":\"Team Work\",\"32\":\"Problem Solving\",\"33\":\"Conflict Management\",\"34\":\"Productivity\",\"35\":\"How would you describe good\\/effective communication? Please share an example of a time that you've seen it in action and an example of when you saw that good communication skills were clearly lacking.\",\"36\":\"How have you handled working under someone you felt was not good at communicating?\",\"37\":\"If you're trying to get your point across or convince somebody that your idea is the right one, what do you do?\",\"38\":\"Who do you think is a good communicator and why? What can we learn from them?\",\"39\":\"Talk about a time that you needed to adapt to a new situation. What did you find difficult and how did you work through that? How can somebody prepare to be more adaptable in future situations?\",\"40\":\"When you're in a situation where it feels like you have no control over it (i.e. a new manager, starting in a new job, government-led changes etc), what do you do to focus on what you can do?\",\"41\":\"How do you handle having multiple priorities at the same time?\",\"42\":\"How do you adjust to different work settings? For example, working with different teams, switching between logic and creativity, learning new processes, tools or technologies?\",\"43\":\"How do you feel about working in a team? What do you think are the key things that need to happen to make good teamwork?\",\"44\":\"What has been your experience of working in teams where there were problems? Did these arise due to strong personalities, somebody not sharing the workload, miscommunication, the wrong support or technology systems etc?\",\"45\":\"How do you keep a team motivated? Share your story about a rewarding team experience.\",\"46\":\"When you're in a team situation, what role do you usually play?\",\"47\":\"Describe a situation where you had to solve a problem. What did you do? what was the result? What might you have done differently?\",\"48\":\"What steps do you take before making a decision on how to solve a problem, and why?\",\"49\":\"Give an example of a situation in which you saw an opportunity in a potential problem. What did you do? What was the outcome?\",\"50\":\"Can you tell me about a situation where you overcame a problem using a creative solution?\",\"51\":\"Have you ever had a team member who kept raising objections on projects? How did you (or would you) manage them?\",\"52\":\"You have noticed that a team member is aggressive or arrogant toward the rest of the team. How would you approach this person?\",\"53\":\"What would you do if your manager gave you negative feedback on the way you approached a problem? How do give negative\\/constructive feedback to others?\",\"54\":\"How could you use a situation with conflict to have a better relationship with all involved?\",\"55\":\"How would you describe a typical working day in your current role? How you manage importance versus urgency? How do you maintain a work-life balance also?\",\"56\":\"If you have your day planned out to achieve a goal, how do you manage distractions or other things that can happen along the way?\",\"57\":\"What do you think very productive people do differently than others?\",\"58\":\"What holds people back from being more productive? How can people turn those around so that by doing the opposite, they can become more productive?\",\"59\":\"Have you ever had a team member who kept raising objections on projects? How did you (or would you) manage them?\",\"60\":\"How do you describe your leadership style?\",\"61\":\"What was a difficult decision you had to make as a leader, and how did you come to that decision?\",\"62\":\"What are the most important attributes of successful leaders today? Who do you think is a good leader and why?\"},\"session_type_id\":{\"0\":1.0,\"1\":1.0,\"2\":1.0,\"3\":1.0,\"4\":2.0,\"5\":2.0,\"6\":2.0,\"7\":2.0,\"8\":3.0,\"9\":3.0,\"10\":3.0,\"11\":3.0,\"12\":4.0,\"13\":4.0,\"14\":4.0,\"15\":4.0,\"16\":5.0,\"17\":5.0,\"18\":5.0,\"19\":5.0,\"20\":6.0,\"21\":6.0,\"22\":6.0,\"23\":6.0,\"24\":7.0,\"25\":7.0,\"26\":7.0,\"27\":7.0,\"28\":8.0,\"29\":8.0,\"30\":8.0,\"31\":8.0,\"32\":8.0,\"33\":8.0,\"34\":8.0,\"35\":null,\"36\":null,\"37\":null,\"38\":null,\"39\":null,\"40\":null,\"41\":null,\"42\":null,\"43\":null,\"44\":null,\"45\":null,\"46\":null,\"47\":null,\"48\":null,\"49\":null,\"50\":null,\"51\":null,\"52\":null,\"53\":null,\"54\":null,\"55\":null,\"56\":null,\"57\":null,\"58\":null,\"59\":null,\"60\":null,\"61\":null,\"62\":null},\"session_type_name\":{\"0\":\"Learning and Development\",\"1\":\"Learning and Development\",\"2\":\"Learning and Development\",\"3\":\"Learning and Development\",\"4\":\"Mentoring\",\"5\":\"Mentoring\",\"6\":\"Mentoring\",\"7\":\"Mentoring\",\"8\":\"Coaching\",\"9\":\"Coaching\",\"10\":\"Coaching\",\"11\":\"Coaching\",\"12\":\"Experience Sharing\",\"13\":\"Experience Sharing\",\"14\":\"Experience Sharing\",\"15\":\"Experience Sharing\",\"16\":\"Networking\",\"17\":\"Networking\",\"18\":\"Networking\",\"19\":\"Networking\",\"20\":\"Establishing Buy-In\",\"21\":\"Establishing Buy-In\",\"22\":\"Establishing Buy-In\",\"23\":\"Establishing Buy-In\",\"24\":\"Idea Exploration\",\"25\":\"Idea Exploration\",\"26\":\"Idea Exploration\",\"27\":\"Idea Exploration\",\"28\":\"Seven Soft Skills\",\"29\":\"Seven Soft Skills\",\"30\":\"Seven Soft Skills\",\"31\":\"Seven Soft Skills\",\"32\":\"Seven Soft Skills\",\"33\":\"Seven Soft Skills\",\"34\":\"Seven Soft Skills\",\"35\":null,\"36\":null,\"37\":null,\"38\":null,\"39\":null,\"40\":null,\"41\":null,\"42\":null,\"43\":null,\"44\":null,\"45\":null,\"46\":null,\"47\":null,\"48\":null,\"49\":null,\"50\":null,\"51\":null,\"52\":null,\"53\":null,\"54\":null,\"55\":null,\"56\":null,\"57\":null,\"58\":null,\"59\":null,\"60\":null,\"61\":null,\"62\":null},\"parent_id\":{\"0\":null,\"1\":null,\"2\":null,\"3\":null,\"4\":null,\"5\":null,\"6\":null,\"7\":null,\"8\":null,\"9\":null,\"10\":null,\"11\":null,\"12\":null,\"13\":null,\"14\":null,\"15\":null,\"16\":null,\"17\":null,\"18\":null,\"19\":null,\"20\":null,\"21\":null,\"22\":null,\"23\":null,\"24\":null,\"25\":null,\"26\":null,\"27\":null,\"28\":null,\"29\":null,\"30\":null,\"31\":null,\"32\":null,\"33\":null,\"34\":null,\"35\":30.0,\"36\":30.0,\"37\":30.0,\"38\":30.0,\"39\":31.0,\"40\":31.0,\"41\":31.0,\"42\":31.0,\"43\":32.0,\"44\":32.0,\"45\":32.0,\"46\":32.0,\"47\":33.0,\"48\":33.0,\"49\":33.0,\"50\":33.0,\"51\":34.0,\"52\":34.0,\"53\":34.0,\"54\":34.0,\"55\":35.0,\"56\":35.0,\"57\":35.0,\"58\":35.0,\"59\":29.0,\"60\":29.0,\"61\":29.0,\"62\":29.0}}"
]
I need to extract data from the 3rd line.
The below code tries to extract the first set of questions from the 3rd line.
import 'dart:core';
import 'dart:convert';
import 'package:http/http.dart' as http;
class Question {
late final String question;
Question({ required this.question});
}
void getData() async{
List<Question> sample_data = [];
String link = 'https://activepeersai.computing.dcu.ie/API/631';
var url = Uri.parse(link);
var result = await http
.get(url,headers: {"Accept": "application/json","Access-Control_Allow_Origin": "*"});
if(result.statusCode==200){
var data = jsonDecode(result.body);
var res = jsonDecode(data[2]);
String round1 = json.encode(res);
var data1 = jsonDecode(round1);
var questions = jsonDecode(data1[0]);
for(var k in questions.keys){
if(((k=='question1')|| (k=='question2') || (k=='question3') || (k=='question4') || (k=='question5') || (k=='question6') || (k=='question7') || (k=='question8') || (k=='question9') || (k=='question10'))){
Question question = Question(question: res[k]);
sample_data.add(question);
}
}
print('$sample_data');
}
}
void main() {
getData();
}
Now when I print round1 I get the below output.
{"0":{"feedback_id":114,"timer_used":1,"timer":10,"question1":"How to break ice with strangers (in social gathering & in formal events) ?","question2":"How to build networking (with those from different age, culture, education background, language…)(in university & in workplace) ?","question3":"","question4":"","question5":"","question6":"","question7":"","question8":"","question9":"","question10":""},"1":{"feedback_id":115,"timer_used":1,"timer":10,"question1":"How to deal with difficult teammates (dominating / debater character / negative / lack of confidence / free rider…) ?","question2":"How to build mutual trust with teammates ?","question3":"","question4":"","question5":"","question6":"","question7":"","question8":"","question9":"","question10":""}}
Which when I checked on Json Checker came to be valid.
But after this I get an error.
Error: Expected a value of type 'String', but got one of type 'Null'
at Object.throw_ [as throw] (http://localhost:56003/dart_sdk.js:5080:11)
at Object.castError (http://localhost:56003/dart_sdk.js:5039:15)
at Object.cast [as as] (http://localhost:56003/dart_sdk.js:5356:17)
at String.as (http://localhost:56003/dart_sdk.js:46240:19)
at getData (http://localhost:56003/packages/testing_for_data/main.dart.lib.js:74:56)
at getData.next (<anonymous>)
at http://localhost:56003/dart_sdk.js:40641:33
at _RootZone.runUnary (http://localhost:56003/dart_sdk.js:40511:59)
at _FutureListener.thenAwait.handleValue (http://localhost:56003/dart_sdk.js:35438:29)
at handleValueCallback (http://localhost:56003/dart_sdk.js:35999:49)
at _Future._propagateToListeners (http://localhost:56003/dart_sdk.js:36037:17)
at [_completeWithValue] (http://localhost:56003/dart_sdk.js:35872:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:56003/dart_sdk.js:35906:35)
at Object._microtaskLoop (http://localhost:56003/dart_sdk.js:40778:13)
at _startMicrotaskLoop (http://localhost:56003/dart_sdk.js:40784:13)
at http://localhost:56003/dart_sdk.js:36261:9
Can someone tell me what I am doing wrong?
Its coming due to the line
var data1 = jsonDecode(round1);
I believe this line is wrong
var questions = jsonDecode(data1[0]);
Firstly, because you probably need data1['0'] instead of data1[0]. They key is a string, not a number.
Secondly. You don't need to decode it again. It's already decoded. So try
var questions = data1['0'];
The next thing is that
Question question = Question(question: res[k]);
needs to be changed to
Question question = Question(question: questions[k]);
Because you actually want it from the questions.
If you want it to print the question instead of Instance of 'Question' you can add a toString method to it, for example:
class Question {
late final String question;
Question({ required this.question});
#override
String toString() {
return question;
}
}

Best practice for interface design

I am wondering which version is the best one to implement.
The parameters are states that have 2 possible values.
This is an abstract example of the actual problem.
I am programming in a language that is procedural (without classes) and does not have typed variable.
I just read an article stating that version 1 is bad for readability and the caller. Personally I don't like version 2 either. Maybe there is a better option?
Version 1:
doSth(par1, par2)
Not redundant +
Single Method for a task +
More complex implementation -
Wrong parameters can be passed easily -
Version 2:
doSthWithPar1Is1AndPar2Is1()
doSthWithPar1Is1AndPar2Is2()
doSthWithPar1Is2AndPar2Is1()
doSthWithPar1Is2AndPar2Is2()
Redundant -
Too many methods (especially with more parameters) -
Long Method Names -
Simple implementation +
No parameters that could be passed wrong +
Given that you already have considered V1 feasible tells me, that the different argument value combinations have something in common with regards to how the values are to be processed.
In V2 you simply have to type and read more, which I'd say is the single most frequent reason for introducing errors/incorrectness and lose track of your requirements.
In V2 you have to repeat what is common in the individual implementations and if you make a mistake, the overall logic will be inconsistent at best. And if you want to fix it, you probably have to fix it in several places.
But, you can optimize code safety based on V1: choose a more "verbose" name for the procedure, like
doSomethingVerySpecificWithPar1OfTypeXAppliedToPar2OfTypeY(par1, par2)
(I am exaggerating a bit...) so you see immediately what you have originally intended.
You could even take the best out of V2 and introduce the individual functions, which simply redirect to the common function of V1 (so you avoid the redundancy). The gain in clarity almost always outweighs the slight loss of efficiency.
doSthWithPar1Is1AndPar2Is1()
{
doSomethingVerySpecificWithPar1OfTypeXAppliedToPar2OfTypeY(1, 1);
}
Always remember David Wheeler: "All problems in computer science can be solved by another level of indirection".
Btw: I don't consider long method names a problem but rather a benefit (up to a certain length of course).

Monads - where are they necessary?

The other day I was talking about functional programming - especially Haskell with some Java/Scala guys and they asked me what are Monads and where are they necessary.
Well the definition and examples were not that hard - Maybe Monad, IO Monad, State Monad etc., so everyone was, at least partially, ok with me saying Monads are a good thing.
But where are Monads necessary - Maybe can be avoided via magic values like -1 in the setting of Integer, or "" in the setting of String. I have written a game without the State Monad, which is not nice at all but beginners do that.
So my question: Where are Monads necessary ? - and cannot be avoided at all.
(And no confusion - I like Monads and use them, I just want to know).
EDIT
I think I have to clarify that I do not think using "Magic Values" is a good solution, but a lot of programmers use them, especially in low level languages as C or in SHell scrips where an error is often implied by returning -1.
It was already clear to me that not using monads isn't a good idea. Abstraction is often very helpful, but also complicated to get, hence many a people struggle with the concept of monads.
The very core of my question was if it was possible to do for example IO, without a monad and still being pure and functional. I knew it would be tedious and painful to put a known good solution aside, as well as lighting a fire with flint and tinder instead of using a lighter.
The article #Antal S-Z refers to is great you could have invented monads, I skimmed over it, and will definitely read it when I have more time. The more revealing answer is hidden in the comment with the blog post referred to by #Antal S-Z i remember the time before monads, which was the stuff I was looking for when I asked the question.
I don't think you ever need monads. They're just a pattern that shows up naturally when you're working with certain kinds of function. The best explanation of this point of view that I've ever seen is Dan Piponi (sigfpe)'s excellent blog post "You Could Have Invented Monads! (And Maybe You Already Have.)", which this answer is inspired by.
You say you wrote a game without using the state monad. What did it look like? There's a good chance you ended up working with functions with types that looked something like openChest :: Player -> Location -> (Item,Player) (which opens a chest, maybe damages the player with a trap, and returns the found item). Once you need to combine those, you can either do so manually (let (item,player') = openChest player loc ; (x,player'') = func2 player' y in ...) or reimplement the state monad's >>= operator.
Or suppose that we're working in a language with hash maps/associative arrays, and we're not working with monads. We need to look up a few items and work with them; maybe we're trying to send a message between two users.
send username1 username2 = {
user1 = users[username1]
user2 = users[username2]
sendMessage user1 user2 messageBody
}
But wait, this won't work; username1 and username2 might be missing, in which case they'll be nil or -1 or something instead of the desired value. Or maybe looking up a key in an associative array returns a value of type Maybe a, so this will even be a type error. Instead, we've got to write something like
send username1 username2 = {
user1 = users[username1]
if (user1 == nil) return
user2 = users[username2]
if (user2 == nil) return
sendMessage user1 user2 messageBody
}
Or, using Maybe,
send username1 username2 =
case users[username1] of
Just user1 -> case users[username2] of
Just user2 -> Just $ sendMessage user1 user2 messageBody
Nothing -> Nothing
Nothing -> Nothing
Ick! This is messy and overly nested. So we define some sort of function which combines possibly-failing actions. Maybe something like
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
f >>= Just x = f x
f >>= Nothing = Nothing
So you can write
send username1 username2 =
users[username1] >>= $ \user1 ->
users[username2] >>= $ \user2 ->
Just (sendMessage user1 user2 messageBody)
If you really didn't want to use Maybe, then you could implement
f >>= x = if x == nil then nil else f x
The same principle applies.
Really, though, I recommend reading "You Could Have Invented Monads!" It's where I got this intuition for monads, and explains it better and in more detail. Monads arise naturally when working with certain types. Sometimes you make that structure explicit and sometimes you don't, but just because you're refraining from it doesn't mean it's not there. You never need to use monads in the sense that you don't need to work with that specific structure, but often it's a natural thing to do. And recognizing the common pattern, here as in many other things, can allow you to write some nicely general code.
(Also, as the second example I used shows, note that you've thrown the baby out with the bathwater by replacing Maybe with magic values. Just because Maybe is a monad doesn't mean you have to use it like one; lists are also monads, as are functions (of the form r ->), but you don't propose getting rid of them! :-))
I could take the phrase "where is/are X necessary and unavoidable?" where X is anything at all in computing; what would be the point?
Instead, I think it's more valuable to ask, "what value do/does X provide?"".
And the most basic answer is that most X's in computing provide a useful abstraction that makes it easier, less tedious, and less error-prone to put code together.
Okay, but you don't need the abstraction, right? I mean, I could just type out a little code by hand that does the same thing, right? Yeah, of course, it's all just a bunch of 0's and 1's, so let's see who can write an XML parser faster, me using Java/Haskell/C or you with a Turing machine.
Re monads: since monads typically deal with effectful computations, this abstraction is most useful when composing effectful functions.
I take issue with your "magic values Maybe monad". That approach offers a very different abstraction to the programmer, and is less safe, more tedious, and more error prone to deal with than an actual Maybe monad. Also, reading such code, the programmer's intent would be less clear. In other words, it misses the whole point of real monads, which is to provide an abstraction.
I'd also like to note that monads are not fundamental to Haskell:
do-notation is simply syntactic sugar, and can be entirely replaced by >>= and >> without any loss of expressiveness
they (and their combinators, such as join, >>=, mapM, etc.) can be written in Haskell
they can be written in any language that supports higher-order functions, or even in Java using objects. So if you had to work with a Lisp that didn't have monads, you could implement them in that Lisp yourself without too much trouble
Because monad types return an answer of the same type, implementations of that monad type can enforce & preserve semantics. Then, in your code, you can chain operations with that type & let it enforce its rules, regardless of the type(s) it contained.
For example, the Optional class in Java 8 enforces the rule that the contained value is either present & non-null, or else not present. As long as you are using the Optional class, with or without using flatMap, you are wrapping that rule around the contained data type. No one can cheat or forget and add a value=null with present=true.
So declaring outside the code that -1 will be a sentinel value and mean such-and-such is fine, but you are still reliant on yourself and the other people working in the code to honor that semantic. If a new guy comes on board and starts using -1000000 to mean the same thing, then the semantics need to be enforced outside the code (perhaps with a lead pipe?) rather than through code mechanisms.
So rather than having to apply some rule consistently in your program, you can trust the monad to preserve that rule (or other semantics) -- over arbitrary types.
In this way, you can extend functionality of types by wrapping semantics around them, instead of, say, adding an "isPresent" to every type in your code base.
The presence of the numerous monadic utility types points to the fact that this mechanism of wrapping types with semantics is a pretty useful trick. If you have your own semantics that you'd like to add, you can do that by writing your own class using the monad pattern, and then inject strings or floats or ints or whatever into it.
But the short answer is that monads are a nice way to wrap common types in a fluent or chain-able container to add rules and usage without having to fuss with the implementation of the underlying types.

What is such a thing called?

I want to know if there is a name for a function/method/library that converts a given date object with time information into something like:
a few seconds ago
2 minutes ago
about an hour ago
10 hours ago
yesterday
on 12-May-2010
and so on. I don't know what to google for, but I'm guessing that someone must have done this before. I'm specifically looking for an implementation in python (preferably a Django filter) that works on a datetime, but any open source implementation in any language will do really, for inspiration.
Google for "Fuzzy Date Time"
I believe it is called "fuzzy timestamp" (also "timedelta")
ruby and python examples are available in this SO question
git has its own date.c utility source for this kind of refspec date specification.
A ref followed by the suffix # with a date specification enclosed in a brace pair (e.g. {yesterday}, {1 month 2 weeks 3 days 1 hour 1 second ago} or {1979-02-26 18:30:00}) to specify the value of the ref at a prior point in time.
I don't really know the name of the method used, but you can find a Javascript implementation of what you're describing at DateJS.

How can I program a simple chat bot AI?

I want to build a bot that asks someone a few simple questions and branches based on the answer. I realize parsing meaning from the human responses will be challenging, but how do you setup the program to deal with the "state" of the conversation?
It will be a one-to-one conversation between a human and the bot.
You probably want to look into Markov Chains as the basics for the bot AI. I wrote something a long time ago (the code to which I'm not proud of at all, and needs some mods to run on Python > 1.5) that may be a useful starting place for you: http://sourceforge.net/projects/benzo/
EDIT: Here's a minimal example in Python of a Markov Chain that accepts input from stdin and outputs text based on the probabilities of words succeeding one another in the input. It's optimized for IRC-style chat logs, but running any decent-sized text through it should demonstrate the concepts:
import random, sys
NONWORD = "\n"
STARTKEY = NONWORD, NONWORD
MAXGEN=1000
class MarkovChainer(object):
def __init__(self):
self.state = dict()
def input(self, input):
word1, word2 = STARTKEY
for word3 in input.split():
self.state.setdefault((word1, word2), list()).append(word3)
word1, word2 = word2, word3
self.state.setdefault((word1, word2), list()).append(NONWORD)
def output(self):
output = list()
word1, word2 = STARTKEY
for i in range(MAXGEN):
word3 = random.choice(self.state[(word1,word2)])
if word3 == NONWORD: break
output.append(word3)
word1, word2 = word2, word3
return " ".join(output)
if __name__ == "__main__":
c = MarkovChainer()
c.input(sys.stdin.read())
print c.output()
It's pretty easy from here to plug in persistence and an IRC library and have the basis of the type of bot you're talking about.
Folks have mentioned already that statefulness isn't a big component of typical chatbots:
a pure Markov implementations may express a very loose sort of state if it is growing its lexicon and table in real time—earlier utterances by the human interlocutor may get regurgitated by chance later in the conversation—but the Markov model doesn't have any inherent mechanism for selecting or producing such responses.
a parsing-based bot (e.g. ELIZA) generally attempts to respond to (some of the) semantic content of the most recent input from the user without significant regard for prior exchanges.
That said, you certainly can add some amount of state to a chatbot, regardless of the input-parsing and statement-synthesis model you're using. How to do that depends a lot on what you want to accomplish with your statefulness, and that's not really clear from your question. A couple general ideas, however:
Create a keyword stack. As your human offers input, parse out keywords from their statements/questions and throw those keywords onto a stack of some sort. When your chatbot fails to come up with something compelling to respond to in the most recent input—or, perhaps, just at random, to mix things up—go back to your stack, grab a previous keyword, and use that to seed your next synthesis. For bonus points, have the bot explicitly acknowledge that it's going back to a previous subject, e.g. "Wait, HUMAN, earlier you mentioned foo. [Sentence seeded by foo]".
Build RPG-like dialogue logic into the bot. As your parsing human input, toggle flags for specific conversational prompts or content from the user and conditionally alter what the chatbot can talk about, or how it communicates. For example, a chatbot bristling (or scolding, or laughing) at foul language is fairly common; a chatbot that will get het up, and conditionally remain so until apologized to, would be an interesting stateful variation on this. Switch output to ALL CAPS, throw in confrontational rhetoric or demands or sobbing, etc.
Can you clarify a little what you want the state to help you accomplish?
Imagine a neural network with parsing capabilities in each node or neuron. Depending on rules and parsing results, neurons fire. If certain neurons fire, you get a good idea about topic and semantic of the question and therefore can give a good answer.
Memory is done by keeping topics talked about in a session, adding to the firing for the next question, and therefore guiding the selection process of possible answers at the end.
Keep your rules and patterns in a knowledge base, but compile them into memory at start time, with a neuron per rule. You can engineer synapses using something like listeners or event functions.
I think you can look at the code for Kooky, and IIRC it also uses Markov Chains.
Also check out the kooky quotes, they were featured on Coding Horror not long ago and some are hilarious.
I think to start this project, it would be good to have a database with questions (organized as a tree. In every node one or more questions).
These questions sould be answered with "yes " or "no".
If the bot starts to question, it can start with any question from yuor database of questions marked as a start-question. The answer is the way to the next node in the tree.
Edit: Here is a somple one written in ruby you can start with: rubyBOT
naive chatbot program. No parsing, no cleverness, just a training file and output.
It first trains itself on a text and then later uses the data from that training to generate responses to the interlocutor’s input. The training process creates a dictionary where each key is a word and the value is a list of all the words that follow that word sequentially anywhere in the training text. If a word features more than once in this list then that reflects and it is more likely to be chosen by the bot, no need for probabilistic stuff just do it with a list.
The bot chooses a random word from your input and generates a response by choosing another random word that has been seen to be a successor to its held word. It then repeats the process by finding a successor to that word in turn and carrying on iteratively until it thinks it’s said enough. It reaches that conclusion by stopping at a word that was prior to a punctuation mark in the training text. It then returns to input mode again to let you respond, and so on.
It isn’t very realistic but I hereby challenge anyone to do better in 71 lines of code !! This is a great challenge for any budding Pythonists, and I just wish I could open the challenge to a wider audience than the small number of visitors I get to this blog. To code a bot that is always guaranteed to be grammatical must surely be closer to several hundred lines, I simplified hugely by just trying to think of the simplest rule to give the computer a mere stab at having something to say.
Its responses are rather impressionistic to say the least ! Also you have to put what you say in single quotes.
I used War and Peace for my “corpus” which took a couple of hours for the training run, use a shorter file if you are impatient…
here is the trainer
#lukebot-trainer.py
import pickle
b=open('war&peace.txt')
text=[]
for line in b:
for word in line.split():
text.append (word)
b.close()
textset=list(set(text))
follow={}
for l in range(len(textset)):
working=[]
check=textset[l]
for w in range(len(text)-1):
if check==text[w] and text[w][-1] not in '(),.?!':
working.append(str(text[w+1]))
follow[check]=working
a=open('lexicon-luke','wb')
pickle.dump(follow,a,2)
a.close()
here is the bot
#lukebot.py
import pickle,random
a=open('lexicon-luke','rb')
successorlist=pickle.load(a)
a.close()
def nextword(a):
if a in successorlist:
return random.choice(successorlist[a])
else:
return 'the'
speech=''
while speech!='quit':
speech=raw_input('>')
s=random.choice(speech.split())
response=''
while True:
neword=nextword(s)
response+=' '+neword
s=neword
if neword[-1] in ',?!.':
break
print response
You tend to get an uncanny feeling when it says something that seems partially to make sense.
I would suggest looking at Bayesian probabilities. Then just monitor the chat room for a period of time to create your probability tree.
I'm not sure this is what you're looking for, but there's an old program called ELIZA which could hold a conversation by taking what you said and spitting it back at you after performing some simple textual transformations.
If I remember correctly, many people were convinced that they were "talking" to a real person and had long elaborate conversations with it.
If you're just dabbling, I believe Pidgin allows you to script chat style behavior. Part of the framework probably tacks the state of who sent the message when, and you'd want to keep a log of your bot's internal state for each of the last N messages. Future state decisions could be hardcoded based on inspection of previous states and the content of the most recent few messages. Or you could do something like the Markov chains discussed and use it both for parsing and generating.
If you do not require a learning bot, using AIML (http://www.aiml.net/) will most likely produce the result you want, at least with respect to the bot parsing input and answering based on it.
You would reuse or create "brains" made of XML (in the AIML-format) and parse/run them in a program (parser). There are parsers made in several different languages to choose from, and as far as I can tell the code seems to be open source in most cases.
You can use "ChatterBot", and host it locally using - 'flask-chatterbot-master"
Links:
[ChatterBot Installation]
https://chatterbot.readthedocs.io/en/stable/setup.html
[Host Locally using - flask-chatterbot-master]: https://github.com/chamkank/flask-chatterbot
Cheers,
Ratnakar