Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Development

Closed Thread
 
Thread Tools Search this Thread Display Modes
Old 6th November 2013, 02:28   #221  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
As a novice AviSynth user I had this problem a few times, and when someone is new to AVS this could be kind of a turn off. Now that I know better and I'm used to this behavior would I like to see a change? Not really, but a more comprehensive error message would definitely be a good idea.

@TurboPascal7
On a side note, any plans to integrate FTurn into AviSynth+?

Last edited by Reel.Deel; 6th November 2013 at 02:49. Reason: FTurn comment
Reel.Deel is offline  
Old 6th November 2013, 03:06   #222  |  Link
wOxxOm
Oz of the zOo
 
Join Date: May 2005
Posts: 208
On the 'last':
  1. a typical mix of filter calls and assignment statements:
    mainfilter1()
    b = auxfilter()
    # last = mainfilter1() as expected
    mainfilter2()
    -----
  2. now someone commented out just the last line knowing how 'last' clip is usually preserved over assignment statements, thus expecting the 'last' clip to carry result of the last filter applied in - what should we call it? - the main flow of the filter graph.
    mainfilter1()
    b = auxfilter()
    # mainfilter2()
    last = nothing????

So, irregardless of user experience, there seems to be no logic *syntax-wise* behind current behavior (but of course if one looks into the source code it's clear that filters() explicitly try to use the 'last' clip in rather an unsightly manner, which doesn't compensate the lack of syntax logic anyway).
wOxxOm is offline  
Old 6th November 2013, 03:08   #223  |  Link
TurboPascal7
Registered User
 
TurboPascal7's Avatar
 
Join Date: Jan 2010
Posts: 270
Quote:
Originally Posted by Reel.Deel View Post
On a side note, any plans to integrate FTurn into AviSynth+?
Will be in the next version or the one after that.
__________________
Me on GitHub | AviSynth+ - the (dead) future of AviSynth
TurboPascal7 is offline  
Old 6th November 2013, 07:58   #224  |  Link
Daiz
Registered User
 
Join Date: Jan 2008
Location: Finland
Posts: 68
Quote:
Originally Posted by TurboPascal7 View Post
Not a clip
I've run into this so many times I've lost count, usually in the exact situation described (testing filtering and commenting out a line), so here's a very large "yes, please make assignment return last" from here.
__________________
Where did neuron1 go? | Doom10
Daiz is offline  
Old 6th November 2013, 10:38   #225  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Quote:
Originally Posted by Gavino View Post
However, a script that ends with an assignment is probably wrong. Why assign to a variable that will never be used?
Who knows what the user intended in such a case?
Perhaps he meant to return the value being assigned, rather than a 'last' that may have been set many lines earlier.
So I think it is better to keep the existing scheme, which forces the user to make the intention clear.
Exactly my thoughts. Also, less experienced users would probably in many cases not know what the script returns with this modification.
When you write a function in C for example, the compiler forces you to return from that function with the correct type and that makes sense. You don't dumb down the language because of convenience.
Groucho2004 is offline  
Old 6th November 2013, 10:56   #226  |  Link
TurboPascal7
Registered User
 
TurboPascal7's Avatar
 
Join Date: Jan 2010
Posts: 270
Quote:
Originally Posted by Groucho2004 View Post
Exactly my thoughts. Also, less experienced users would probably in many cases not know what the script returns with this modification.
When you write a function in C for example, the compiler forces you to return from that function with the correct type and that makes sense. You don't dumb down the language because of convenience.
Avisynth is not C. Stop applying rules of normal languages to it. You don't want to write "return derp" in the end of every function/script, do you?

As for assignment on the last line being wrong argument, what about scripts like this:
Code:
super=MSuper(last, pel=4, planar=true)
pp_super=fft3dgpu().MSuper(pel=4, planar=true)

b1vec = MAnalyse(super, delta=1, isb=true, blksize=8, overlap=4,search=5)
f1vec = MAnalyse(super, delta=1, blksize=8, overlap=4,search=5)

b1clip = MCompensate(orig, super, b1vec, thSAD=400)
f1clip = MCompensate(orig, super, f1vec, thSAD=400)
Whoops, variable pp_super is unused, the user ended up calculating vectors on the wrong clip. This is a bug. And we did exactly nothing to prevent it. Now please explain me the reason why we should do something to prevent this kind of behavior if this assignment happens on the last line. Because it's easier to implement? Because it's always been like this? I think we either go full way preventing users from shooting in their own feet and forbid unused variables altogether (this is a bad idea please don't even consider this) or drop this kind of argument.

As for users not knowing what script returns: if this behavior got silently changed, how many people do you think would notice?

P.S. I'm sorry if I sound too "rude" and I should probably stop posting on the issue. The question was posted to get opinions, not arguing about them. Sorry.
__________________
Me on GitHub | AviSynth+ - the (dead) future of AviSynth

Last edited by TurboPascal7; 6th November 2013 at 11:06. Reason: Millions of typos
TurboPascal7 is offline  
Old 6th November 2013, 11:07   #227  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Quote:
Originally Posted by TurboPascal7 View Post
Avisynth is not C.
Thank you for your wise words. I was using it as an example, not to be taken literally. The logic still applies. Your logic is just different.
Quote:
Originally Posted by TurboPascal7 View Post
You don't want to write "return derp" in the end of every function/script, do you?
I kinda do...
Groucho2004 is offline  
Old 6th November 2013, 11:17   #228  |  Link
Sapo84
Registered User
 
Join Date: May 2008
Posts: 40
Quote:
Originally Posted by TurboPascal7 View Post
Whoops, variable pp_super is unused, the user ended up calculating vectors on the wrong clip. This is a bug.
It depends, maybe the user was using pp_super before, didn't like the result and stopped using it without removing the variable.

Anyway, I'm against a fix that will allow sloppy coding (commenting lines and leaving an assignment as the last line sounds like sloppy coding to me), instead of commenting just use a return last in the place you need to test the output.
Sapo84 is offline  
Old 6th November 2013, 12:03   #229  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by TurboPascal7 View Post
Now please explain me the reason why we should do something to prevent this kind of behavior if this assignment happens on the last line.
Because in that the case the problem is more than just the unused variable (that's just an aspect I mentioned to illustrate that the script was incomplete). The issue is that the intended return value is not clear.

Quote:
Originally Posted by Sapo84 View Post
instead of commenting just use a return last in the place you need to test the output.
Yes, I was about to make that point myself.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline  
Old 6th November 2013, 12:17   #230  |  Link
wOxxOm
Oz of the zOo
 
Join Date: May 2005
Posts: 208
Commenting was just an example, there's no need to focus on that per se.

The real problem is the quirky behavior of an assignment statement in avisynth at the end of a scope.
It is inconsistent.

Either make all assignment statements kill the 'last' clip (nonsense), or make the last assignment behave exactly the same as the others.
wOxxOm is offline  
Old 6th November 2013, 12:24   #231  |  Link
TurboPascal7
Registered User
 
TurboPascal7's Avatar
 
Join Date: Jan 2010
Posts: 270
Quote:
Originally Posted by Gavino View Post
Because in that the case the problem is more than just the unused variable (that's just an aspect I mentioned to illustrate that the script was incomplete). The issue is that the intended return value is not clear.
Code:
function test() {
    colorbars(640, 480)
    clp = blur(1)
}

colorbars(320, 240)
test()
blur(1.0)
What did the user intend to return here? This script actually works, with function basically being a nop() call. Talk about preventing users errors. =)

Anyway, this was actually pointed out as an example where this proposal would break stuff, which for me is a showstopper. So I'm gonna quit here. But I (and not only I) would still love to see your ideas on multithreading.
__________________
Me on GitHub | AviSynth+ - the (dead) future of AviSynth
TurboPascal7 is offline  
Old 6th November 2013, 12:26   #232  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by wOxxOm View Post
make the last assignment behave exactly the same as the others.
It does behave the same as the others, there is no inconsistency.

Note that the commonly held belief that 'last' is returned by default is wrong. See this post.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline  
Old 6th November 2013, 12:37   #233  |  Link
wOxxOm
Oz of the zOo
 
Join Date: May 2005
Posts: 208
Quote:
Originally Posted by Gavino View Post
It does behave the same as the others, there is no inconsistency.
Internally, yes. But not from a user's point of view.
Quote:
Originally Posted by Gavino View Post
Note that the commonly held belief that 'last' is returned by default is wrong.
It's 'wrong' only because of the issue we're talking about.
wOxxOm is offline  
Old 6th November 2013, 13:18   #234  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by wOxxOm View Post
Internally, yes. But not from a user's point of view.
What is the inconsistency from the user's point of view?

Quote:
It's 'wrong' only because of the issue we're talking about.
Not just this issue (assignment) - if the last thing is a non-clip expression (eg an int), 'last' is not returned either, even if set earlier.

The Fluff had an excellent post just now describing how it works in detail, but it seems to have disappeared.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline  
Old 6th November 2013, 13:43   #235  |  Link
wOxxOm
Oz of the zOo
 
Join Date: May 2005
Posts: 208
Quote:
Originally Posted by Gavino View Post
What is the inconsistency from the user's point of view?
Well, I thought it's shown in my posts above...
Quote:
Originally Posted by Gavino View Post
Not just this issue (assignment) - if the last thing is a non-clip expression (eg an int), 'last' is not returned either, even if set earlier.
If it's not an assignment then from user's point of view it's the same as any other filter expression, so the 'last' is returned as expected.
wOxxOm is offline  
Old 6th November 2013, 14:25   #236  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,100
I deleted the post because I thought the discussion had already covered what I was talking about but here's the relevant part again:

Avisynth has four types of expressions:
1) explicit returns ("return <expression>")
2) explicit assignments ("variable = <expression>")
3) implicit assignments to last (all expressions that aren't one of the two first types and evaluate to a clip)
4) other expressions where the return value is thrown away (everything else)

When the last expression in a block (either a function or a script) is not an explicit return (type 1 above), Avisynth will evaluate the expression and implicitly return the value it evaluates to, regardless of what the type of that value is (clip, int, string, undefined, whatever). The quirky thing here is that while expressions of type 3 and 4 above return the value of the expression, an explicit assignment returns an undefined value. I think this is a lazy fix to make sure an explicit assignment of a clip to an arbitrary variable doesn't overwrite last, which I suspect would happen if the assignment returned the assigned value like every other assignment operator on the planet does. The inconsistency is that an explicit assignment returns undefined while an implicit assignment to last returns the assigned value.

What TurboPascal7 proposed to change is simply the implicit return mechanism: if you attempt to implicitly return an explicit assignment expression, last should be returned instead of the undefined value, if last is defined at that point. The problem with this is that there's nothing about the scripting language that forces you to use last, and thus there's really nothing that says that at the end of a block the contents of last would be a better or more correct value to return than any other arbitrary value. I can accept an operator returning an undefined value, even if I think that's ugly, but having an operator return a defined, arbitrary value that may be completely unrelated to any of its operands is beyond ugly.

What I think you should do is promote the assignment operator to full citizen status like all of Avisynth's other operators, give it a place in the precedence table and make it return the assigned value like assignment operators in basically every other language do. Then fix the script parser so this doesn't overwrite last when the assigned value is a clip. This will probably break things though.

Last edited by TheFluff; 6th November 2013 at 14:43.
TheFluff is offline  
Old 6th November 2013, 14:43   #237  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Yesterday we discussed this issue extensively with a couple of folks on IRC, and because there was no consensus, I encouraged them to bring this to the forums, to see what others think. I take Gavino's, Fluff's, Sapo's and Groucho's side here, and their arguments are the same why I wouldn't like to make this modification. To reiterate my points (which practically already have been said here by others), IMHO integrating this fix is not a good idea because:
- It will lead to confusion with non-expert users. If they expect anything to be returned after an assignment, they will expect the assigned value to be returned, not some hidden variable ('last') from a couple of lines earlier.
- More importantly, it can (and probably will) lead to hard-to-discover bugs, even with more experienced users. If the last statement is an assignment, did the user want the assigned value to be returned, or did he forget a line with 'last'? Changing the behavior to which basically equals to adding an implicit 'last' statement will hide one of these errors, while the current behavior makes the user spell out his expectations exactly (which avoids both error possibilities).

Wishful thinking on my part, but if we really wanted to make return values more logical and easier to use, we should either (1) return the last assigned value whatever it is even if not 'last', or (2, preferred) get rid of implicit returns completely and always require a 'return' statement in any block for a variable to be returned. Of course, both of these solutions would seriously break a lot of scripts, so obviously none of these two are gonna happen.
ultim is offline  
Old 6th November 2013, 15:16   #238  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
I don't want to prolong the debate unnecessarily, as it seems we have now reached a conclusion, but just to address a couple of points raised...

Quote:
Originally Posted by wOxxOm View Post
If it's not an assignment then from user's point of view it's the same as any other filter expression, so the 'last' is returned as expected.
Consider
Code:
function f(clip c) {
  c
  ...
  width()
}
Here, we don't have an assignment but an int expression.
The value of that expression is returned rather than the value of 'last' (which is 'c').
(Note that only clip values are ever implicitly assigned to 'last'.)

Quote:
Originally Posted by TheFluff View Post
The inconsistency is that an explicit assignment returns undefined while an implicit assignment to last returns the assigned value.
Strictly speaking, there is no implicit assignment to 'last' on the last statement. Instead, it is treated as an implicit 'return' (and defined this way in the docs).
If you look at it this way, then there is no inconsistency in the treatment of assignments.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline  
Old 6th November 2013, 16:33   #239  |  Link
Lenchik
Registered User
 
Join Date: Nov 2005
Location: Russia
Posts: 62
"nah, this will break my scripts because I found a way to rely on this behavior" or something like that. I got used to current behaviour. And moreover i am often creating chains of scripts by importing them into one biggest. I think that new modification can make more difficulties than making life easier.
Lenchik is offline  
Old 6th November 2013, 18:08   #240  |  Link
SEt
Registered User
 
Join Date: Aug 2007
Posts: 374
Quote:
Originally Posted by TurboPascal7 View Post
You could tell us about this idea of yours instead of just saying you have it, you know.
I doubt anyone it going to implement it, but as you requested, general outline:


In one word I can describe it as "superscalar" architecture. The same ideas as used in modern superscalar CPUs:

1) Work is separated from data flow. (-> denotes function call)
How it goes now: Render->FilterB->FilterA->Source.
How it should be: Scheduler->Source, Scheduler->FilterA, Scheduler->FilterB.
2) Filter has to be able to tell the scheduler which frame numbers from which its sources it needs to produce each destination frame number. Fast, without actual frames, but maybe imprecise (can fail its processing call and request more).
3) There are several kinds of filters: one instance multicall (like MTMode 1), one instance singlecall (MTMode 3), multi instance one call per instance (MTMode 2). Type is provided by the filter itself, always.
4) Based on 1-3, number of available hardware threads and data flow graph Scheduler builds filter call plan in superscalar way: several frames in flight on different stages.
5) Refcounting and no cache. Based on call plan each frame has its own reference count and will be kept exactly until all references are used. All produced frames are read-only, but could be forwarded (for filters like Trim).

As could be seen, such architecture not only would allow efficient and scalable utilization of hardware threads but will be able to incorporate even extremely threading-unfriendly filters with sequential frame processing without any correctness or speed drawbacks given enough other work in script.

Also it would be very memory-efficient: only actually needed data is kept and memory is consumed as much as needed for no redundant work in the scheduling window.

Cons: hard to implement, scheduling is active and will consume some resources, how filters work needs to be modified: source frames are provided to filter, not requested from inside.


Legacy Avisynth 2.5 filters work through separate filter "wrapper". Threading information is provided to it in textual user-editable file config.
SEt is offline  
Closed Thread

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:14.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.