5 ms·
Hmm, I started reading the Wikipedia article on the Pascal programming language. I was reading about the pointer types and saw a 'with' statement... Where did I
by smlckz 6y ago
Hmm, I started reading the Wikipedia article on the Pascal programming language. I was reading about the pointer types and saw a 'with' statement... Where did I see something like that before?... Yes, JavaScript! Where it is highly discouraged to use. How is it like in Pascal?
- FpUser 6y agoIt is discouraged in Pascal as well. Can give really nasty surprises with scoping / debugging. Well to me it is mostly gossip as I refuse to use WITH in my Pascal code so no practical experience.
- fmakunbound 6y agoHeh, thought it was from Lisp. No problem with scoping there.
- kazinator 6y agowith macros in Lisp tend to be sanely designed: they explicitly list the symbols that are to be introduced into the scope. I don't think I've never seen a "bring the whole set of the currently defined slots of this class/struct into this scope as locals". Oh, you can do it. his is the TXR Lisp interactive listener of TXR 249. Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet. Use full-strength TXR for tough tasks, or dilute with shell scripts. 1> (defmacro with (struct obj . body) (with-gensyms (obj-sym) ^(let ((,obj-sym ,obj)) (symacrolet ,(mapcar (op list @1 ^(qref ,obj-sym ,@1)) (slots struct)) ,*body)))) with 2> (with time (time-struct-utc (time)) (list year month day)) (2021 1 30) Expansion: 3> (macroexpand '(with time (time-struct-utc (time)) (list year month day))) (let ((#:g0016 (time-struct-utc (time)))) (symacrolet ((time-local #:g0016.time-local) (time-utc #:g0016.time-utc) (time-string #:g0016.time-string) (time-parse #:g0016.time-parse) (year #:g0016.year) (month #:g0016.month) (day #:g0016.day) (hour #:g0016.hour) (min #:g0016.min) (sec #:g0016.sec) (dst #:g0016.dst) (gmtoff #:g0016.gmtoff) (zone #:g0016.zone)) (list year month day))) Total expansion; symacrolet gone, a.b desugared into (slot a 'b): 4> (expand '(with time (time-struct-utc (time)) (list year month day))) (let ((#:g0017 (time-struct-utc (time)))) (list (slot #:g0017 'year) (slot #:g0017 'month) (slot #:g0017 'day)))
- fiddlerwoaroof 6y agoIt’s different in Pascal l, iirc: in JavaScript with has dynamic scope in and affects every function you call inside the work statement; in Pascal, it has lexical scope. I used it all the time in Delphi and don’t recall any real issues.
- kazinator 6y agoThe Pascal/Modula-2 WITH statement brings all of the members of a record into the lexical scope, without them being mentioned in the statement (i.e. implicitly). So when you add, remove or rename members of a record, you are potentially influencing the contents of scopes in other files all over the project. You can cause variable shadowing that way. VAR B : INTEGER; WITH ^P DO A := B; (* B is just a local, A is a field *) END If B is added as a field, the above suddenly means ^P.A = ^P.B. Any time you edit a Modula-2 record, you have to search the program for all the places where its type may be targeted by WITH. Probably if you stick to some rules, like never using WITH on another module's record type, you will be fine. Diagnostics related to shadowing could help.
- fiddlerwoaroof 6y agoI assume it’s statically checked, so you’ll get a compilation error?
- FpUser 6y agoIt is a habit. I use Delphi all the time even now as one of my currently active projects is written in it. I just do not use WITH.
- deleted 6y ago[deleted]
- jksmith 6y agoMeh, you do have to watch your scope using "with," but it's worth the brevity provided if you write pascal code crafted to be sensitive to unit/class/record dependencies. If I was putting together a team, it might be prudent to include some coding governance around "with" I admit.
- interfixus 6y agoAs I remember it from nearly 25 years ago, with was a safe and straightforward construct to use, as long as you kept it within manageable scopes. Great for saving an extra dereference inside some monster loop when the microseconds really counted.
- kazinator 6y agoC++ class scopes have the with problem. class foo { // int x; int y; int bar(); }; // in another file int x; foo::bar() // "with whole friggin class scope ..." { return x + y; // global ::x plus class member y } Now uncomment the x in the class declaration, and the x + y now adds two class members.