[70404 Closed] How to write something like this in Oxygene (it is from java)?

int length;
while ((length = inStream.read(buffer)) > 0)
{
outStream.write(buffer, 0, length);
}

I tried this (but it doesn’t work) -> oxidizer did the same …

var length : Integer;
while (( length:=insteram.read(buffer))>0)
begin
outstream.write(buffer,0,length)
end;

Mateusz

I think the problem is the dual/combination assignment and comparison:

while ((length := instream.read(buffer)) > 0)

I don’t think this is possible in Pascal/Oxygene. I’m willing to be corrected if Oxygene does or should allow it (why else would Oxydizer emit it, unless of course there is a bug in Oxydizer ?) but would still advise that it be avoided.

In this case, re-write as a repeat…until:

var length : Integer;
repeat
    length := instream.read(buffer);
    if length > 0 then
        outstream.write(buffer,0,length)
until length = 0;

Ok. I will change it :wink:
Thank you :slight_smile:

That sound like a bug in Oxidizer, yes. the while statement does not (currently) support defining a new var.

Thanks, logged as bugs://70404: Oxidizer/Java converts while statement with inline var decl badly

Hi Marc,

I’m curious that you didn’t say that the combination of assignment and comparison isn’t legal, since the problem isn’t the inline variable declaration but the use of an assignment within the conditional expression:

i.e. this doesn’t compile, even when all variables involved are pre-declared:

while ((length := instream.read(buffer)) > 0)

Should this compile ? Will this ever be supported ? (personally I don’t think it should)

I can see a way to make such a loop more explicit. The objective is to initialise a condition variable at the commencement of a loop (initial and repeated) and to loop only if and while that variable meets and continues to meet a condition. This could be achieved by combining a for initialisation clause with a while conditional loop.

This would be a distinct syntax, separated from a regular for loop by the lack of a to clause. In this case, the resulting loop would be:

for length := instread.read(buffer) while length > 0 do
begin
end;

Though not as compact as the C-style combined assignment and comparison, this does simplify the loop structure that is otherwise required with the repeat construct whilst retaining the fact that the two components (assignment and condition) are a key component of the loop.

This would also allow richer combinations of loop initialisation and condition, beyond simply testing a value assigned in the condition:

for length := instread.read(buffer) 
  while (length > 0) and (buffer.Contains('foo')) do
  begin
  end;

The syntactic similarity to the otherwise required repeat loop is striking, especially if you format it to emphasise the similarity:

repeat length := instread.read(buffer) 
  if (length > 0) and (buffer.Contains('foo')) then
  begin
  end;
until (length = 0) or (not buffer.Contains('foo'));

Note however that repeat requires the loop condition to be duplicated, occurring once within the loop and then again, inverted, as the loop condition. ime duplication of conditions is a common cause of bugs, especially where logic inversion is involved and required. True, this could be avoided by a diligent developer by introducing a loop control boolean, but a for .. while grammar eliminates the need for this and would be even cleaner, imho:

Just putting it out there. :slight_smile:

Right; assigning inside an expression isn’t legal in Pascal (and I don’t really want it to be), however Oxidizer should not generate it as is.

Hello,
you can also write the loop as the following, without repeating the condition:

loop begin
  var length := instread.read (buffer);
  if length = 0 then
    break;
  // work on the buffer
end;
1 Like

no. while takes a boolean expression. what yu have is not a boolean expression, it’s a (typeless) assignment statement…

i don’t expect so, no

or by just declaring the variable before the loop :wink:

@Marc, I think you have missed what’s going on. The variable is already declared before the loop. In C the assignment and comparison results in a boolean expression (the result of the comparison of the value that has just been assigned). The problem for this type of loop in Pascal is that there is an operation that demands that an assignment be made prior to each iteration of the loop, but this assigned value then itself determines whether the iteration proceeds.

In any event, I’m relieved to hear that supporting assignment+comparison expressions isn’t on the cards. :slight_smile:

@Patrick, I .wasn’t aware of the unconditional loop statement. Quite cool. I had considered suggesting an exactly equivalent while TRUE but decided not to as many people are uncomfortable with the potential that they perceive this creates for non-terminating loops (slightly irrational imho as the same risk applies if you get your terminal loop condition wrong of course). I use while TRUE myself where it makes sense (usually where the exit conditions are highly conditional and too awkward to be expressed as an explicit loop terminal or entry condition.

But this is a more specialised (yet quite common) case where each loop iteration is dependent on an initial operation which cannot be directly incorporated into the loop condition itself.

You could introduce scaffolding to make the operation yield a result in a form that could be incorporated in the loop condition:

   // Nested/Inner proc where instream, buffer and length are all still in scope
   function ReadBuffer: Boolean
   begin
     length := instream.Read( buffer );
     result := length > 0;
   end;

//...

while ReadBuffer do
begin
end;

But this is probably beyond the capabilities of Oxydizer (?) and even for a human is all very cumbersome and imho obfuscates aspects of the loop which are critical to the correct execution of it, solely to enable one type of loop which isn’t currently supported in the language, to be replaced with another.

The inability to cleanly express this particular sort of loop using for, repeat or while statements has irked me for years, but for some reason it was only in this thread that it occurred to me to combine the for and while as a way to extend the looping facilities in the language.

No biggie if it still never arrives, but I think it would be a very cool addition to Oxygene (and surely not too difficult ?). :slight_smile:

Yes, you’re right, i missed/forgot that aspect, when i wrote my second reply.

indeed. in Oxygene it does not (and should not). hats why this doesn’t (and imho shouldn’t) work

bugs://70404 got closed as fixed for release Constitution Class