From: sinistral
Subject: determining the type of a variable in CL
Date: 
Message-ID: <e2e2f96f-cd85-4f9c-91d3-03507190d622@e4g2000hsg.googlegroups.com>
Greetings all

The subject is perhaps a bit misleading, but I'm not sure to state it
more clearly in a single line.  Allow me to clarify it by presenting a
scenario:

I'm looking at a function that by grep and inspection have determined
to be the location of a piece of problematic functionality in an
unfamiliar codebase.  This method takes a handful of parameters that I
now have to trace back to the original calling method in order to find
out what they actually are.  Or do I?
In statically-typed languages its easy to find out more about the
types in use in a specific context (function or method) because of the
declarations.

I hope that is a useful explanation of what I'm looking for ...

I'm not asking this question to spark any kind of debate about the
merits of dynamic vs static typing...  Much of my programming
experience is in statically-typed languages; I'm trying to learn more
about LISP and its application in large, complex projects, and I'd
appreciate suggestions for techniques to make myself more productive
in this context. I'm asking the question here because I have the
impressions that LISP has been used on more large projects than
languages like PERL or Python (again, as inflamatory as that statement
might be, I'm not trying to start a war ... that's just my
impression), and people here would have more experience in overcoming
these kinds of hurdles.

One of you wizards must have experience in bringing an apprentice up
to speed  : ]

I see this as an issue on projects where there are a number of
developers with various skill levels and I'd appreciate comment from
others who have been involved in those kinds of developments and who
have solved this problem ... or found it to be a non-problem.

Regards,
.marc

From: ······@gmail.com
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <42ca2902-1032-4e51-9855-c1bcd5a9ef85@s8g2000prg.googlegroups.com>
first of all i am not wizard .. i am more a lisp newbie but meaby i
can help a bit :)

well, you need to read the code to know that
if you don't have any declaration in some cases parameters can be
totally different, and function can manually dispatch code base on
parameters
if it would be any help you have: class-name, class-of, type-of ...
best,milan
From: Slobodan Blazeski
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <84ae08bf-aa16-495b-883b-6bdfcbacf1db@i12g2000prf.googlegroups.com>
On Feb 7, 10:32 am, sinistral <·········@gmail.com> wrote:
> Greetings all
>
> The subject is perhaps a bit misleading, but I'm not sure to state it
> more clearly in a single line.  Allow me to clarify it by presenting a
> scenario:
>
> I'm looking at a function that by grep and inspection have determined
> to be the location of a piece of problematic functionality in an
> unfamiliar codebase.  This method takes a handful of parameters that I
> now have to trace back to the original calling method in order to find
> out what they actually are.  Or do I?
The peasant method would be inserting bunch of (princ (type-of
parameter-you-are-interested)) in the code. More sophisticated method
that is implementation dependendent is adding breakpoints and use
inspector to look at parameters.
> In statically-typed languages its easy to find out more about the
> types in use in a specific context (function or method) because of the
> declarations.
I dont' know what good would knowing the types will do.
>
> I hope that is a useful explanation of what I'm looking for ...
The more useful expalnation would be to write the problematic method
and function that calls it.
And state what Os / Implementation you're using.
Even better is to get famigliar with your implementation debugging
facilities. Quality lisps are the strongest in that point than any IDE
I've seen in my life.

cheers
Slobodan
From: levy
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <cf8148c8-5504-43c2-b88a-3c5b4777271e@v46g2000hsv.googlegroups.com>
On the other hand it would be nice to be able to see what type (or
anything else a static analysis can figure out) an expression has in
SLIME just by staying on it for a while with the cursor. The compiler
uses type inference and various other things to analyze the code but
unfortunately very little is instantly visible to the user in SLIME.

There are certainly many ways to improve that.

levy
From: Rainer Joswig
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <joswig-42FA6A.11115807022008@news-europe.giganews.com>
In article 
<····································@e4g2000hsg.googlegroups.com>,
 sinistral <·········@gmail.com> wrote:

> Greetings all
> 
> The subject is perhaps a bit misleading, but I'm not sure to state it
> more clearly in a single line.  Allow me to clarify it by presenting a
> scenario:
> 
> I'm looking at a function that by grep and inspection have determined
> to be the location of a piece of problematic functionality in an
> unfamiliar codebase.  This method takes a handful of parameters that I
> now have to trace back to the original calling method in order to find
> out what they actually are.  Or do I?
> In statically-typed languages its easy to find out more about the
> types in use in a specific context (function or method) because of the
> declarations.
> 
> I hope that is a useful explanation of what I'm looking for ...
> 
> I'm not asking this question to spark any kind of debate about the
> merits of dynamic vs static typing...  Much of my programming
> experience is in statically-typed languages; I'm trying to learn more
> about LISP and its application in large, complex projects, and I'd
> appreciate suggestions for techniques to make myself more productive
> in this context. I'm asking the question here because I have the
> impressions that LISP has been used on more large projects than
> languages like PERL or Python (again, as inflamatory as that statement
> might be, I'm not trying to start a war ... that's just my
> impression), and people here would have more experience in overcoming
> these kinds of hurdles.
> 
> One of you wizards must have experience in bringing an apprentice up
> to speed  : ]
> 
> I see this as an issue on projects where there are a number of
> developers with various skill levels and I'd appreciate comment from
> others who have been involved in those kinds of developments and who
> have solved this problem ... or found it to be a non-problem.
> 
> Regards,
> .marc

Static inspection from source is usually a bit difficult with
Common Lisp. Sometimes type declarations can be very helpful.
Common Lisp allows then in a number of places - for example
for slots of structures and classes. A typical problem
is then that the declarations sometimes are wrong, since
in many Lisp systems they are not enforced. One
that is enforced are calls to CHECK-TYPE .

The problem I usually have is that I not only want to know
the type of some parameter, but I want to see the actual
objects that are typically given to the function and
see what they are.

So, I modify the function so that it does give some information.
I either display that information to some stream, a window
or I record it into some datastructure for later inspection.

* a break point

(defun handle (window message)
   (break)
...)

You can call BREAK also based on some calculation, if
you are only interested for example when an argument
looks 'interesting'.

In some Lisps you can set break points in various ways.
Even conditional break points.

* trace

(trace handle)

In some Lisps you have lots of options to trace to
get information about calls and the results.

http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-107.htm#pgfId-1040564

LispWorks for example allows you to create a backtrace on
each call of a trace function.

  
* inspect

Some implementations pop-up GUI window-based inspectors.

(defun handle (window message)
  (inspect (list 'handle window message))
 ...)

This will pop-up a window inspecting the list. There might
be problems with stack-allocated data.
In some implementations you can do use TRACE to
call such a function.

* advise

Some Lisps can add :before ore :after functionality to
normal functions. You can then add code that records
the parameters

http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-279.htm#defadvice


* profiler

some profilers are able to give information about
function calls and their parameters

* step

 if all fails I step through code and examine
  the arguments more closely

* who-calls

Returns all the functions that call a function.
http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-254.htm#pgfId-940349
From: Ken Tilton
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <47ab2e2f$0$15172$607ed4bc@cv.net>
sinistral wrote:
> Greetings all
> 
> The subject is perhaps a bit misleading, but I'm not sure to state it
> more clearly in a single line.  Allow me to clarify it by presenting a
> scenario:
> 
> I'm looking at a function that by grep and inspection have determined
> to be the location of a piece of problematic functionality in an
> unfamiliar codebase.

Really? How does that work? Was the insulation on the wiring in that 
area melted? Maybe even charred? Was it still smoking from the last time 
you ran it? Did it make funny sounds, like thump-thump-whiz-bump? And 
what was the problematic functionality? Unwanted missile launches 
against Moscow? That would say a lot.

>  This method takes a handful of parameters...

What are their names? What is the functions name? I think if you feed 
that information into your Acme Problematic Functionality Detector it 
will spit out their type info.

>... that I
> now have to trace back to the original calling method in order to find
> out what they actually are.  Or do I?

No, you do not. Everyone in large organizations knows that only the 
original author of a program should maintain it. Page the SOB and tell 
them to fix their damn code. You can give them a headstart by showing 
them the burnt wiring, tho.

> In statically-typed languages its easy to find out more about the
> types in use in a specific context (function or method) because of the
> declarations.

Where I have worked before when asked to work on Someone Else's Code we 
always rewrote it anyway so you could rewrite the thing in Java and then 
use the type information to find the problem. Just thinkin out loud.

> 
> I hope that is a useful explanation of what I'm looking for ...
> 
> I'm not asking this question to spark any kind of debate about the
> merits of dynamic vs static typing... 

Not to worry, static typing has been rejected by anyone with half a 
brain. We just melt down for glue any remaining proponents who come our 
way. Tim has a big vat.

> Much of my programming
> experience is in statically-typed languages; I'm trying to learn more
> about LISP and its application in large, complex projects, and I'd
> appreciate suggestions for techniques to make myself more productive
> in this context.

I think your company has done the right thing, simply throwing you in at 
the deep end of a huge Lisp application whose original developers died 
of substance abuse and sending you to a newsgroup for training. (#lisp 
IRC would be even better, btw.)

> I'm asking the question here because I have the
> impressions that LISP has been used on more large projects than
> languages like PERL or Python (again, as inflamatory as that statement
> might be, I'm not trying to start a war ... that's just my
> impression), and people here would have more experience in overcoming
> these kinds of hurdles.

I use trace.

kenny

-- 
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Pascal J. Bourguignon
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <7cir11rq20.fsf@pbourguignon.anevia.com>
sinistral <·········@gmail.com> writes:
> The subject is perhaps a bit misleading, but I'm not sure to state it
> more clearly in a single line.  [...]

First, you have to understand that in lisp, variables ARE NOT typed.
There is no type attached to variables.

Only _values_ are typed.

Type declarations don't say that such variable will hold data of such
type. They say that such variable will be bound only to _values_ of
such type.

In a way, type inference in lisp is reduced to data flow.  Tell me
what data you put in your variables, and I'll tell you what type (of
data) is stored in this variable.


Now, if you want to inspect the type of a value, you can use TYPE-OF,
SUBTYPEP, TYPEP, etc.

So if you have a function:

(defun mysterious (x y)
   (if (eql x y)
      x
      (mysterious (funny x y) y)))


You could add expressions to print the type-of the variables you want:

(defun mysterious (x y)
   (print `(x is of type ,(type-of x)))
   (print `(y is of type ,(type-of y)))
   (if (eql x y)
      x
      (mysterious (funny x y) y)))


C/USER1[111]> (mysterious 13 13.0)

(X IS OF TYPE (INTEGER 0 16777215)) 
(Y IS OF TYPE SINGLE-FLOAT) 
(X IS OF TYPE SINGLE-FLOAT) 
(Y IS OF TYPE SINGLE-FLOAT) 
13.0
C/USER1[112]> (mysterious 13 13.0d0)

(X IS OF TYPE (INTEGER 0 16777215)) 
(Y IS OF TYPE DOUBLE-FLOAT) 
(X IS OF TYPE DOUBLE-FLOAT) 
(Y IS OF TYPE DOUBLE-FLOAT) 
13.0d0


On the other hand, you can usually know the type of the data by seeing
its printed syntax: 13 is an integer, 13.0 is a single-float, 13.0d0
is a double-float.  So you can just trace the mysterious function and
learn a lot about what kind of object it is passed and what kind of
results it returns:


C/USER1[117]> (trace mysterious)
;; Tracing function MYSTERIOUS.
(MYSTERIOUS)
C/USER1[118]> (mysterious 13 13.0)
 1. Trace: (MYSTERIOUS '13 '13.0)
  2. Trace: (MYSTERIOUS '13.0 '13.0)
  2. Trace: MYSTERIOUS ==> 13.0
 1. Trace: MYSTERIOUS ==> 13.0
13.0
C/USER1[119]> (mysterious 13 13.0d0)
 1. Trace: (MYSTERIOUS '13 '13.0d0)
  2. Trace: (MYSTERIOUS '13.0d0 '13.0d0)
  2. Trace: MYSTERIOUS ==> 13.0d0
 1. Trace: MYSTERIOUS ==> 13.0d0
13.0d0
C/USER1[120]> 


-- 
__Pascal Bourguignon__
From: Alex Mizrahi
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <47aae08e$0$90276$14726298@news.sunsite.dk>
 s> unfamiliar codebase.  This method takes a handful of parameters that I
 s> now have to trace back to the original calling method in order to find
 s> out what they actually are.  Or do I?
 s> In statically-typed languages its easy to find out more about the
 s> types in use in a specific context (function or method) because of the
 s> declarations.

and in dynamic-typed languages it is easy to find out more about the types 
in use in specific context .. in runtime.

there are plenty of ways to do inspection, as other people pointed out.

but i wonder what stopped you from inserting PRINTs in the function of 
interest and see what parameters are. isn't that obvious? 
From: Don Geddis
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <87d4r8pkbl.fsf@geddis.org>
sinistral <·········@gmail.com> wrote on Thu, 7 Feb 2008 :
> I'm looking at a function that by grep and inspection have determined
> to be the location of a piece of problematic functionality in an
> unfamiliar codebase.  This method takes a handful of parameters that I
> now have to trace back to the original calling method in order to find
> out what they actually are.
[...]
> In statically-typed languages its easy to find out more about the
> types in use in a specific context (function or method) because of the
> declarations.
[...]
> I'd appreciate comment from others who have been involved in those kinds of
> developments and who have solved this problem ... or found it to be a
> non-problem.

Others have answered your direct question, e.g. using TYPE-OF and friends.

As for your meta-question, you're basically barking up the wrong tree.
Determining the data type of values passed to a function is generally a
very, very minor part of debugging a broken function.

Your problem is that you've got a function that doesn't work quite right,
and you need to fix it.  Lisps offer all sorts of tools for debugging.
You can get at some data type information if you really want to, but that's
rarely on the critical path to debugging broken functions.

What you need to learn is not how to find data types, but instead how to
debug in Lisp.

        -- Don

P.S. As others have suggested, might as well start by adding PRINT statements
to the broken function...
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
I think there are some things you can only learn by experience.  Like, never
put an ice cube down the back of somebody who's shooting a bow and arrow.
	-- Deep Thoughts, by Jack Handey [1999]
From: sinistral
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <6178e5b3-85bb-4c50-ac24-75063b8ec434@1g2000hsl.googlegroups.com>
My thanks to everyone who has responded.

The use of something like PRINT did occur to me (and is something I
use quite often), but I was wondering if there were any techniques for
inspecting the code without getting it running first.

To put approach in perspective: I used to work for a company where it
was felt that it was more efficient to walk through the code and debug
by inspection (i.e. by reading code), rather than by getting something
up and running.  It's not an approach to debugging that I've always
been entirely comfortable with, but is one that over the years I've
gotten used to.

With LISP, I guess I'm going to have to learn new techniques...  Like
making damn sure that we have a complete unit test suite that one can
use to quickly and easily check the behaviour of a function.

Again, my thanks to all who took the time to help me out.
.marc
From: Duane Rettig
Subject: Re: determining the type of a variable in CL
Date: 
Message-ID: <o0bq6nv4w8.fsf@gemini.franz.com>
sinistral <·········@gmail.com> writes:

> To put approach in perspective: I used to work for a company where it
> was felt that it was more efficient to walk through the code and debug
> by inspection (i.e. by reading code), rather than by getting something
> up and running.  It's not an approach to debugging that I've always
> been entirely comfortable with, but is one that over the years I've
> gotten used to.

Code Reading is indeed a Good Thing.  A good code reader can point out
areas in another's code that isn't very readable, and can even notice
bugs (perhaps bad logic, perhaps missing elements of functionality),
and thought experiments can indeed find deep bugs that are extremely
hard to test.  I wouldn't give up the idea of code reading, just
because you're using Lisp now.  However, note well that you can't
code-read your own code; going over your own code right after you've
written it might show you a few trivial "stupid mistakes", but never
the deeper issues that code reading is so good for.  On the third
hand, reviewing your code 6 months after you've written it can be just
like someone else reading it (how many times have you come across old
code you've written and said "Did I really write that?" :-)

> With LISP, I guess I'm going to have to learn new techniques...  Like
> making damn sure that we have a complete unit test suite that one can
> use to quickly and easily check the behaviour of a function.

But that's always the right approach, no matter what language you are
using.  Perhaps the company you were working for had a skewed approach
to design and testing?  No matter what language it is written in, code
that isn't unit-tested as well as system-tested is brittle, just as
hardware that has not had its subcomponents tested will have a much
higher failure rate than hardware that goes through series' of tests
at each stage of assembly.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182