script property changes within handler don't stick?

OK, here’s one that seems strange to me. I’ve read the discussion of the differences between properties and global and local variables and how they are scoped. But I have a list declared as a property that IS visible to a handler in the script (as it should be) but when I update the list (add an item) within the handler, the added item is visible within the handler (it’s been added to the list) but when I come out of the handler and re-enter it the added list item is gone (or ignored by contains).

I’m working on what will eventually be a chatbot (or chatterbox), a program that “chats” in an intelligent fashion. So far I’m still breaking down the input sentence for meaning, but I intend to allow the program to “learn” by adding items to the appropriate lists (noun, pronoun, etc.). But if the added item doesn’t “stick” then I’m sunk. Here’s the script:

property question : {"who", "what", "when", "where", "how", "why"}
property article : {"a", "an", "the"}
property conjunction : {"and", "but", "or"}
property negation : {"not"}
property noun : {"computer", "boy", "girl", "man", "woman", "answer", "name"}
property adverb : {"quickly", "slowly", "happily", "quietly"}
property subjectpronoun : {"I", "you", "they", "we", "he", "she", "it"}
property verb : {"am", "is", "are", "like", "want", "give", "take", "go", "goes", "do", "does", "have", "has"}
property objectpronoun : {"me", "you", "them", "us", "him", "her", "it"}
property possessive : {"my", "mine", "your", "yours", "his", "hers", "its", "their", "theirs", "our", "ours"}
property adjective : {"big", "small", "black", "white", "fat", "thin", "happy", "sad"}
property mypreposition : {"to", "on", "with", "around", "near", "without"}
property parts : {"noun", "verb", "article", "conjunction", "negation", "adverb", "subjectpronoun", "objectpronoun", "possessive", "adjective", "preposition"}
property partList : {noun, verb, article, conjunction, negation, adverb, subjectpronoun, objectpronoun, possessive, adjective, mypreposition}
copy AppleScript's text item delimiters to astid
set text item delimiters to space
set myCmd to ""

repeat while myCmd is not "quit"
	set myCmd to text returned of (display dialog "Talk to me" default answer "")
	display dialog analyzeSentence(myCmd) as string
end repeat

copy astid to text item delimiters

-- handlers for dialog
to analyzeSentence(theSentence)
	set thePattern to {}
	
	repeat with myWord in (words of theSentence)
		ignoring case
			if (myWord is in subjectpronoun) and (myWord is in objectpronoun) then
				if thePattern ends with "verb" then
					set thePattern to thePattern & "objectpronoun"
				else
					set thePattern to thePattern & "subjectpronoun"
				end if
			else
				
				if question contains myWord then
					set thePattern to thePattern & "?"
				else if (article contains myWord) then
					set thePattern to thePattern & "article"
				else if (noun contains myWord) then
					set thePattern to thePattern & "noun"
				else if (conjunction contains myWord) then
					set thePattern to thePattern & "conjunction"
				else if (possessive contains myWord) then
					set thePattern to thePattern & "possessive"
				else if (subjectpronoun contains myWord) then
					set thePattern to thePattern & "subjectpronoun"
				else if (verb contains myWord) then
					set thePattern to thePattern & "verb"
				else if (adverb contains myWord) then
					set thePattern to thePattern & "adverb"
				else if (objectpronoun contains myWord) then
					set thePattern to thePattern & "objectpronoun"
				else if (adjective contains myWord) then
					set thePattern to thePattern & "adjective"
				else if (mypreposition contains myWord) then
					set thePattern to thePattern & "preposition"
				else
					set myPrompt to " What kind of word is " & myWord & "?"
					set thePart to choose from list parts with prompt (myPrompt as string)
					set myItem to 1
					set found to false
					repeat while not found
						if thePart as string = item myItem of parts then
							
							set (item myItem of partList) to (item myItem of partList & myWord)
							set found to true
							set thePattern to thePattern & thePart
							--display the list with the added word
							display dialog (item myItem of partList) as string
						end if
						set myItem to myItem + 1
					end repeat
				end if
			end if
		end ignoring
	end repeat
	return thePattern
end analyzeSentence

Try running the program and using a new word (“dog” or “brown” or both) and it will ask you to pick the part of speech the word belongs to. The next time through the parser, though, it doesn’t recognize the new word, even though it’s been added to the list.

Is this aberrant behavior on the part of AppleScript? Or did I miss something in the discussion of scope?

Model: iMac DV+ (450mhz), 384mb, 40gb HD
AppleScript: 1.9.1
Browser: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.1) Gecko/20060214 Camino/1.0
Operating System: Mac OS X (10.2.x)

Where in your script do you modify a property?

Edited: nevermind, I found it:

set (item myItem of partList) to (item myItem of partList & myWord)

There’s something more than just not remembering what’s been added, Kevin. Try this sentence: “I do not like computer”. The code asks me to parse “not” which is clearly listed in negation.

If you want to add items to a list, then something like this:

set the_list to {1, 2, 3}
set end of the_list to 4
set beginning of the_list to 0
return the_list

gl,

That’s my fault. If you check the “else if” block, I never tested for it or added that line.

“Curiouser and curiouser,” said Alice.
– Alice’s Adventures in Wonderland.

I tried using the list form kel suggested:

and now we get really strange. Whereas the & version of the item addition worked for the local handler (the display dialog showed the new item added to the list), using the “end of” form doesn’t work. The list remains unchanged, and no error is thrown.

MAN. This is weird. Because kel’s version works all by itself (the 0 and 4 are added at the beginning and end of the list in the above example).

I don’t understand this at all.

Jacques!Jacques!Jacques!Jacques!Jacques!:lol:

You did it! That form works and the added list items are retained! So it seems that the correct reference form DOES make a difference, even though the other form works for most things. I’ll bet when this stuff was in development, they tested the correct reference forms and never thought about other forms that should work, so they didn’t test them.

OK, now I can keep working on my script!

Thanks kel, Adam, and Jacques. Team Macscripter triumphs again!

Hi,

Good catch Jacques. I was just starting to break down the script.

Kevin,

The bug(?) is in the string coercion. Usually an error would occur, but for some reason there is none when coercing references to list items.

set l1 to {“a”, “b”, “c”}
set l2 to {“d”, “e”}
repeat with this_item in l1
set end of l2 to this_item
exit repeat
end repeat
{l2, l2 as string}

this_item is a reference to an item in list 1.

gl,

Also, of course, as kel and Jacques must have noticed, by using concatenation in this line:

… item myItem of partList was being set to a completely new list ” that is, a different list from the property that was used to set it in the property declarations at the top of the script. The next time the script was run, the list in partList did in fact contain the additional word, but the other properties (noun, verb, article, etc.) were still pointing to the original lists, which didn’t.

By using ‘set end of’, which appends an item to an existing list rather than creating a new one, item myItem of partList remains the list pointed to by the original property. Any items added to it are then visible when the list is accessed via that property.

Later addition to post:

I think that should be “… when coercing lists that contain references.” When a list containing a reference is coerced to string, the reference ” and anything after it in the list ” isn’t apparently coerced or included in the final result. This is a long-standing issue. I don’t know if it’s a bug or not, but it annoys a lot of people. :wink:

kel wrote:

Nigel wrote:

Thanks guys, but I think the real bug is in the scripter who didn’t know how to handle lists properly. :confused:

Lists are something I’ve not dealt with since Apple Logo (yeah, that long ago…). It’s taking some getting used to, but the power inherent in list-processing is amazing, especially when dealing with language (which, as I understand it, is the reason that lists were used a lot in AI stuff like Lisp).

I am sufficiently ashamed that I will never misuse lists again (ok, no guarantees).

Hi Nigel,

Thanks for clearing this up Nigel. The bug(?) is in the coercion of a list that contains a reference to a list item and not the reference to the list item coercion to string. I miss-worded my post.

gl,