Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Eiffel (programming language)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Agents=== Eiffel's "agent" mechanism wraps operations into objects. This mechanism can be used for iteration, [[event-driven programming]], and other contexts in which it is useful to pass operations around the program structure. Other programming languages, especially ones that emphasize [[functional programming]], allow a similar pattern using [[continuations]], [[closure (computer science)|closures]], or [[generator (computer science)|generators]]; Eiffel's agents emphasize the language's object-oriented paradigm, and use a syntax and semantics similar to code blocks in [[Smalltalk]] and [[Ruby (programming language)|Ruby]]. For example, to execute the <code>my_action</code> block for each element of <code>my_list</code>, one would write: <syntaxhighlight lang="eiffel"> my_list.do_all (agent my_action) </syntaxhighlight> To execute <code>my_action</code> only on elements satisfying <code>my_condition</code>, a limitation/filter can be added: <syntaxhighlight lang="eiffel"> my_list.do_if (agent my_action, agent my_condition) </syntaxhighlight> In these examples, <code>my_action</code> and <code>my_condition</code> are routines. Prefixing them with <code>agent</code> yields an object that represents the corresponding routine with all its properties, in particular the ability to be called with the appropriate arguments. So if <code>a</code> represents that object (for example because <code>a</code> is the argument to <code>do_all</code>), the instruction <syntaxhighlight lang="eiffel"> a.call ([x]) </syntaxhighlight> will call the original routine with the argument <code>x</code>, as if we had directly called the original routine: <code>my_action (x)</code>. Arguments to <code>call</code> are passed as a tuple, here <code>[x]</code>. It is possible to keep some arguments to an agent '''open''' and make others '''closed'''. The open arguments are passed as arguments to <code>call</code>: they are provided at the time of ''agent use''. The closed arguments are provided at the time of agent ''definition''. For example, if <code>action2</code> has two arguments, the iteration <syntaxhighlight lang="eiffel"> my_list.do_all (agent action2 (?, y)) </syntaxhighlight> iterates <code>action2 (x, y)</code> for successive values of <code>x</code>, where the second argument remains set to <code>y</code>. The question mark <code>?</code> indicates an open argument; <code>y</code> is a closed argument of the agent. Note that the basic syntax <code>agent f</code> is a shorthand for <code>agent f (?, ?, ...)</code> with all arguments open. It is also possible to make the ''target'' of an agent open through the notation <code>{T}?</code> where <code>T</code> is the type of the target. The distinction between open and closed operands (operands = arguments + target) corresponds to the distinction between bound and free variables in [[lambda calculus]]. An agent expression such as <code>action2 (?, y)</code> with some operands closed and some open corresponds to a version of the original operation ''[[currying|curried]]'' on the closed operands. The agent mechanism also allows defining an agent without reference to an existing routine (such as <code>my_action</code>, <code>my_condition</code>, <code>action2</code>), through inline agents as in <syntaxhighlight lang="eiffel"> my_list.do_all (agent (s: STRING) require not_void: s /= Void do s.append_character (',') ensure appended: s.count = old s.count + 1 end) </syntaxhighlight> The inline agent passed here can have all the trappings of a normal routine, including precondition, postcondition, rescue clause (not used here), and a full signature. This avoids defining routines when all that's needed is a computation to be wrapped in an agent. This is useful in particular for contracts, as in an invariant clause that expresses that all elements of a list are positive: <syntaxhighlight lang="eiffel"> my_list.for_all (agent (x: INTEGER): BOOLEAN do Result := (x > 0) end) </syntaxhighlight> The current agent mechanism leaves a possibility of run-time type error (if a routine with ''n'' arguments is passed to an agent expecting ''m'' arguments with ''m'' < ''n''). This can be avoided by a run-time check through the precondition <code>valid_arguments</code> of <code>call</code>. Several proposals for a purely static correction of this problem are available, including a language change proposal by Ribet et al.<ref>Philippe Ribet, Cyril Adrian, Olivier Zendra, Dominique Colnet: ''Conformance of agents in the Eiffel language'', in ''[[JOT: Journal of Object Technology|Journal of Object Technology]]'', vol. 3, no. 4, April 2004, Special issue: TOOLS USA 2003, pp. 125-143. Available on line from the [http://www.jot.fm/issues/issue_2004_04/article7 JOT article page]</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)