Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#7482 closed enhancement (fixed)

provide a mode so that undeclared variables magically spring into existence and object oriented notation is not necessary

Reported by: was Owned by: tbd
Priority: major Milestone: sage-4.3.1
Component: misc Keywords:
Cc: Merged in: sage-4.3.1.alpha0
Authors: William Stein Reviewers: Mitesh Patel
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description (last modified by was)

This depends on #7514.

College teacher often say that by far the biggest obstruction to people switching from Maple to Sage is that:

(1) symbolic variables don't magically spring into existence when used

(2) one has to use object oriented notation---foo.bar(...)---to access methods of an object.

Attachments (5)

sagenb_7482.patch (7.4 KB) - added by was 11 years ago.
apply to the sagenb spkg
sagelib_7482.patch (612 bytes) - added by was 11 years ago.
apply to the core sage library
sagenb_7482.2.patch (7.4 KB) - added by mpatel 11 years ago.
Fix typo. Replaces sagenb patch.
sagenb_7482.3.patch (7.4 KB) - added by mpatel 11 years ago.
Suppress a doctest (cf. #7650). Replaces sagenb patch.
sagenb_7482.4.patch (8.5 KB) - added by mpatel 11 years ago.
Rebased vs. #7514's "part3.2". Replaces sagenb patch.

Download all attachments as: .zip

Change History (20)

comment:1 Changed 11 years ago by was

I have created a "mock up" of the above functionality, for people to play with, which doesn't even require applying a patch. Just paste the following into a Sage notebook cell and press shift-enter:

class MagicVar(Expression):
    def __call__(self, *args, **kwds):
        return args[0].__getattribute__(str(self))(*args[1:], **kwds)

class MagicNames:
    def eval(self, s, globals, locals=None):
        x = preparse(s).strip()
        y = x.split('\n')
        if len(y) == 0:
            return ''
        s = '\n'.join(y[:-1]) + '\n'
        t = y[-1]
        try:
            z = compile(t + '\n', '', 'single')
        except SyntaxError:
            s += '\n' + t
            z = None
        while True:
            try:    
                self._eval_code(s, z, globals)
            except NameError, msg:
                nm = msg.args[0].split("'")[1]
                globals[nm] = MagicVar(SR, var(nm))
            else:
                return ''
                
    def _eval_code(self, s, z, globals):
        eval(compile(s, '', 'exec'), globals, globals)
        if z is not None:
            eval(z, globals)
        
magic = MagicNames()                 

Now if you put %magic at the top of an input cell, then symbolic variables magically spring into life, and object oriented notation is not necessary. There isn't an easy way to make this permanent for all cells in a worksheet (without putting %magic) without actually changing the sage library with a patch. This is because of a major annoying mistake I found just now (see #7483).

comment:2 Changed 11 years ago by was

  • Description modified (diff)

I'm attaching a patch that fully implements this in the notebook, via a command automatic_names(True). This depends on trac #7483. I could not figure out how to implement this on the command line without making potentially major changes to IPython, which is a bad idea at this point. So this will be notebook only. Since the target audience is newbie calculus freshman, restricting to the notebook probably isn't much of a constraint.

comment:3 Changed 11 years ago by was

Here is a session (to be used in the notebook) that illustrates automatic_names:

sage: automatic_names(True)
sage: x + y + z + wxy
wxy + x + y + z
sage: y(y=10)
10
sage: type(y)
<class 'sagenb.misc.support.AutomaticVariable'>
sage: trig_expand((2*x + 4*y + sin(2*theta))^2)
4*(sin(theta)*cos(theta) + x + 2*y)^2
sage: type(trig_expand)
<class 'sagenb.misc.support.AutomaticVariable'>
sage: type(x)
<type 'sage.symbolic.expression.Expression'>
sage: type(y)
<class 'sagenb.misc.support.AutomaticVariable'>

Notice above that trig_expand, y, and theta were all automatically created. Notice that substitution y(y=10) still works. If an object obj had a y method, then y(obj) would be evaluated as obj.y().

Here's a test showing that we avoid infinite loops:

sage: raise NameError
Traceback (most recent call last):
...
NameError
sage: raise NameError, "'var'"
Traceback (most recent call last):
...
NameError: Too many automatic variable names and functions created (limit=10000)

Changed 11 years ago by was

apply to the sagenb spkg

Changed 11 years ago by was

apply to the core sage library

comment:4 Changed 11 years ago by was

  • Status changed from new to needs_review

comment:5 Changed 11 years ago by was

I've put a new sagenb spkg with just this patch (and the one from 7483) here:

http://wstein.org/home/wstein/patches/sagenb/sagenb-0.4.3.p1.spkg

comment:6 Changed 11 years ago by mpatel

The Selenium test results are unchanged in FF3.5.5 on Linux.

make ptest on sage.math passes.

comment:7 Changed 11 years ago by was

I'm making implementing this for IPython as trac #7486.

comment:8 Changed 11 years ago by mpatel

This looks good to and works for me, but it'd be great to get additional data.

Please try the demo at alpha.sagenb.org!

comment:9 Changed 11 years ago by mpatel

  • Authors set to William Stein
  • Report Upstream set to N/A
  • Reviewers set to Mitesh Patel
  • Status changed from needs_review to positive_review

This is very clever! In

so that ``foo(bar, ...)`` gets transformed to ``foo.bar(...)``.

should the latter be ``bar.foo(...)``?

Should we advertise automatic_names on sage-edu?

Changed 11 years ago by mpatel

Fix typo. Replaces sagenb patch.

comment:10 Changed 11 years ago by mpatel

V3 changes

            sage: automatic_names(True)

to

            sage: automatic_names(True)      # not tested

Changed 11 years ago by mpatel

Suppress a doctest (cf. #7650). Replaces sagenb patch.

comment:11 Changed 11 years ago by mhansen

Once this is merged in sagenb, I'll merge the code in sagelib.

comment:12 Changed 11 years ago by was

  • Description modified (diff)

Changed 11 years ago by mpatel

Rebased vs. #7514's "part3.2". Replaces sagenb patch.

comment:13 Changed 11 years ago by mhansen

I've merged the sagelib patch in 4.3.1.alpha0.

comment:14 Changed 11 years ago by was

  • Resolution set to fixed
  • Status changed from positive_review to closed

Merged into sagenb-0.4.8.

comment:15 Changed 11 years ago by kcrisman

  • Merged in set to sage-4.3.1.alpha0
Note: See TracTickets for help on using tickets.